windows-nt/Source/XPSP1/NT/drivers/wdm/audio/legacy/wdmaud.drv/wdmdrv.h

692 lines
14 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/****************************************************************************
*
* wdmdrv.h
*
* Function declarations, etc. for WDMAUD.DRV
*
* Copyright (C) Microsoft Corporation, 1997 - 1999 All Rights Reserved.
*
* History
* 5-12-97 - Noel Cross (NoelC)
*
***************************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
#include <string.h>
#include <stdio.h>
#include <windows.h>
#include <windowsx.h>
#include <mmsystem.h>
#include <mmddk.h>
#include <ks.h>
#include <ksmedia.h>
#include <setupapi.h>
#ifdef UNDER_NT
#if (DBG)
#define DEBUG
#endif
#endif
#include <wdmaud.h>
#include <midi.h>
/***************************************************************************
DEBUGGING SUPPORT
***************************************************************************/
#ifdef DEBUG
extern VOID FAR __cdecl wdmaudDbgOut(LPSTR lpszFormat, ...);
extern UINT uiDebugLevel; // debug level
extern char szReturningErrorStr[];
extern char *MsgToAscii(ULONG ulMsg);
//
// Debug message levels:
//
#define DL_ERROR 0x00000000
#define DL_WARNING 0x00000001
#define DL_TRACE 0x00000002
#define DL_MAX 0x00000004
#define DL_MASK 0x000000FF
//
// 20 bits reserved for functional areas. If we find that this bit is set
// in the DebugLevel variable, we will display every message of this type.
//
#define FA_AUX 0x80000000
#define FA_DEVICEIO 0x40000000
#define FA_SETUP 0x20000000
#define FA_MIDI 0x10000000
#define FA_WAVE 0x08000000
#define FA_RECORD 0x04000000
#define FA_EVENT 0x02000000
#define FA_MIXER 0x01000000
#define FA_DRV 0x00800000
#define FA_ASSERT 0x00400000
#define FA_RETURN 0x00200000
#define FA_SYNC 0x00100000
#define FA_MASK 0xFFFFF000
#define FA_ALL 0x00001000
extern VOID
wdmaudDbgBreakPoint(
);
extern UINT
wdmaudDbgPreCheckLevel(
UINT uiMsgLevel,
char *pFunction,
int iLine
);
extern UINT
wdmaudDbgPostCheckLevel(
UINT uiMsgLevel
);
extern char *
wdmaudReturnString(
ULONG ulMsg
);
extern char szReturningErrorStr[];
//----------------------------------------------------------------------------
//
// This debug macro is used like this:
//
// DPF(DL_WARNING|FA_MIXER,("Message %X %X %X ...",x,y,z,...) );
//
// The output for this message will look like:
//
// WDMAUD.DRV FooFunction Warning Message 5 6 7 - Set BP on 64003452 to DBG
//
// The only difference between this code and the code in wdmaud.sys is that
// to break in the debugger, you call DbgBreak() and to display a string you
// call OutputDebugString(...).
//
// The call to wdmaudDbgPreCheckLevel displays:
//
// "WDMAUD.DRV FooFunction Warning "
//
// The call to wdmaudDbgOut displays the actual message
//
// "Message 5 6 7 ..."
//
// and the call to wdmaudDbgPostCheckLevel finishs the line
//
// " - Set BP on 64003452 to DBG"
//
//----------------------------------------------------------------------------
#define DPF(_x_,_y_) {if( wdmaudDbgPreCheckLevel(_x_,__FUNCTION__,__LINE__) ) { wdmaudDbgOut _y_; \
wdmaudDbgPostCheckLevel( _x_ ); }}
//
// Warning: Do not rap function calls in this return macro! Notice that
// _mmr_ is used more then once, thus the function call would be made more
// than once!
//
#define MMRRETURN( _mmr_ ) {if ( _mmr_ != MMSYSERR_NOERROR) \
{ DPF(DL_WARNING|FA_RETURN, (szReturningErrorStr, _mmr_,MsgToAscii(_mmr_)) ); } \
return _mmr_;}
//
// It's bad form to put more then one expression in an assert macro. Why? because
// you will not know exactly what expression failed the assert!
//
// dDbgAssert should be:
//
#define DPFASSERT(_exp_) {if( !(_exp_) ) {DPF(DL_ERROR|FA_ASSERT,("'%s'",#_exp_) );}}
// #define WinAssert(exp) ((exp) ? (VOID)0 : dDbgAssert(#exp, __FILE__, __LINE__))
#define DbgBreak() DebugBreak()
// The path trap macro ...
#define DPFBTRAP() DPF(DL_ERROR|FA_ASSERT,("Path Trap, Please report") );
//
// There are a number of internal structures that we want to keep tabs on. In
// every case, there will be a signature in the structure that we can use when
// verifying the content.
//
#define WAVEPREPAREDATA_SIGNATURE 'DPPW' //WPPD as seen in memory
#define MIXERINSTANCE_SIGNATURE 'IMAW' // WAMI as seen in memory
#else
#define DPF( _x_,_y_ )
#define MMRRETURN( _mmr_ ) return (_mmr_)
#define DPFASSERT(x) 0
#define DbgBreak()
#endif
#ifdef DEBUG
//
// Here are a couple of defines used to look for corruption paths
//
#define FOURTYTHREE 0x43434343
#define FOURTYTWO 0x42424242
#define FOURTYEIGHT 0x48484848
#else
#define FOURTYTHREE NULL
#define FOURTYTWO NULL
#define FOURTYEIGHT NULL
#endif
/***************************************************************************
UNICODE SUPPORT
***************************************************************************/
//
// Taken from winnt.h
//
// Neutral ANSI/UNICODE types and macros
//
#ifdef UNICODE
#ifndef _TCHAR_DEFINED
typedef WCHAR TCHAR, *PTCHAR;
#define _TCHAR_DEFINED
#define TEXT(quote) L##quote
#endif /* !_TCHAR_DEFINED */
#else /* UNICODE */
#ifndef _TCHAR_DEFINED
typedef char TCHAR, *PTCHAR;
#define _TCHAR_DEFINED
#define TEXT(quote) quote
#endif /* !_TCHAR_DEFINED */
#endif /* UNICODE */
/****************************************************************************
Random defines and global variables
***************************************************************************/
#define WDMAUD_MAX_DEVICES 100
extern LPDEVICEINFO pWaveDeviceList;
extern LPDEVICEINFO pMidiDeviceList;
extern CRITICAL_SECTION wdmaudCritSec;
#ifdef UNDER_NT
#define CRITENTER EnterCriticalSection( (LPCRITICAL_SECTION)DeviceInfo->DeviceState->csQueue )
#define CRITLEAVE LeaveCriticalSection( (LPCRITICAL_SECTION)DeviceInfo->DeviceState->csQueue )
#else
extern WORD gwCritLevel ; // critical section counter
#define CRITENTER if (!(gwCritLevel++)) _asm { cli }
#define CRITLEAVE if (!(--gwCritLevel)) _asm { sti }
#endif
#ifdef UNDER_NT
#define CALLBACKARRAYSIZE 128
typedef struct {
DWORD dwID;
DWORD dwCallbackType;
} CBINFO;
typedef struct {
ULONG GlobalIndex;
CBINFO Callbacks[CALLBACKARRAYSIZE];
} CALLBACKS, *PCALLBACKS;
#endif
//
// These two macros are for validating error return codes from wdmaud.sys.
//
// This first one sets the input and output buffer for a DeviceIoControl call to
// a known bad value.
//
#define PRESETERROR(_di) _di->mmr=0xDEADBEEF
//
// This macro reads: if the return value from wdmaudIoControl is SUCCESS THEN
// check to see if there was an error code placed in the device info structure.
// If so (we don't find DEADBEEF there), that is the real error value to return.
// But, if during the call the value didn't get set, we'll find DEADBEEF in the
// error location! Thus,the check for DEADBEEF that simply restores the device
// info mmr entry to SUCCESS.
//
#define POSTEXTRACTERROR(r, _di) if( r == MMSYSERR_NOERROR ) { \
if( _di->mmr != 0xDEADBEEF ) { \
r = _di->mmr; \
} else { \
DPF(DL_TRACE|FA_DEVICEIO, ("wdmaudIoControl didn't set mmr %X:%s", r, MsgToAscii(r)) ); \
_di->mmr = MMSYSERR_NOERROR; } }
#define EXTRACTERROR(r, _di) if( r == MMSYSERR_NOERROR ) { r = _di->mmr; }
/****************************************************************************
Struture definitions
***************************************************************************/
typedef struct _WAVEPREPAREDATA
{
struct _DEVICEINFO FAR *pdi;
LPOVERLAPPED pOverlapped; // Overlapped structure
// for completion
#ifdef DEBUG
DWORD dwSig; // WPPD
#endif
} WAVEPREPAREDATA, FAR *PWAVEPREPAREDATA;
/****************************************************************************
Driver entry points
***************************************************************************/
BOOL FAR PASCAL LibMain
(
HANDLE hInstance,
WORD wHeapSize,
LPSTR lpszCmdLine
);
BOOL WINAPI DllEntryPoint
(
HINSTANCE hinstDLL,
DWORD fdwReason,
LPVOID lpvReserved
);
LRESULT _loadds CALLBACK DriverProc
(
DWORD id,
HDRVR hDriver,
WORD msg,
LPARAM lParam1,
LPARAM lParam2
);
DWORD FAR PASCAL _loadds wodMessage
(
UINT id,
UINT msg,
DWORD_PTR dwUser,
DWORD_PTR dwParam1,
DWORD_PTR dwParam2
);
DWORD FAR PASCAL _loadds widMessage
(
UINT id,
UINT msg,
DWORD_PTR dwUser,
DWORD_PTR dwParam1,
DWORD_PTR dwParam2
);
DWORD FAR PASCAL _loadds modMessage
(
UINT id,
UINT msg,
DWORD_PTR dwUser,
DWORD_PTR dwParam1,
DWORD_PTR dwParam2
);
DWORD FAR PASCAL _loadds midMessage
(
UINT id,
UINT msg,
DWORD_PTR dwUser,
DWORD_PTR dwParam1,
DWORD_PTR dwParam2
);
DWORD FAR PASCAL _loadds mxdMessage
(
UINT id,
UINT msg,
DWORD_PTR dwUser,
DWORD_PTR dwParam1,
DWORD_PTR dwParam2
);
/****************************************************************************
Local routines
***************************************************************************/
BOOL DrvInit();
HANDLE wdmaOpenKernelDevice();
VOID DrvEnd();
LPDEVICEINFO GlobalAllocDeviceInfo(LPCWSTR DeviceInterface);
VOID GlobalFreeDeviceInfo(LPDEVICEINFO lpdi);
MMRESULT wdmaudOpenDev
(
LPDEVICEINFO DeviceInfo,
LPWAVEFORMATEX lpWaveFormat
);
MMRESULT FAR wdmaudCloseDev
(
LPDEVICEINFO DeviceInfo
);
MMRESULT FAR wdmaudGetDevCaps
(
LPDEVICEINFO DeviceInfo,
MDEVICECAPSEX FAR *MediaDeviceCapsEx
);
DWORD FAR wdmaudGetNumDevs
(
UINT DeviceType,
LPCWSTR DeviceInterface
);
DWORD FAR wdmaudAddRemoveDevNode
(
UINT DeviceType,
LPCWSTR DeviceInterface,
BOOL fAdd
);
DWORD FAR wdmaudSetPreferredDevice
(
UINT DeviceType,
UINT DeviceNumber,
DWORD_PTR dwParam1,
DWORD_PTR dwParam2
);
MMRESULT FAR wdmaudIoControl
(
LPDEVICEINFO DeviceInfo,
DWORD dwSize,
LPVOID pData,
ULONG IoCode
);
MMRESULT wdmaudSetDeviceState
(
LPDEVICEINFO DeviceInfo,
ULONG IoCode
);
MMRESULT wdmaudGetPos
(
LPDEVICEINFO pClient,
LPMMTIME lpmmt,
DWORD dwSize,
UINT DeviceType
);
VOID FAR midiCallback
(
LPDEVICEINFO pMidi,
UINT msg,
DWORD_PTR dw1,
DWORD_PTR dw2
);
MMRESULT FAR midiOpen
(
LPDEVICEINFO DeviceInfo,
DWORD_PTR dwUser,
LPMIDIOPENDESC pmod,
DWORD dwParam2
);
VOID FAR midiCleanUp
(
LPDEVICEINFO pClient
);
MMRESULT midiInRead
(
LPDEVICEINFO pClient,
LPMIDIHDR pHdr
);
MMRESULT FAR midiOutWrite
(
LPDEVICEINFO pClient,
DWORD ulEvent
);
VOID FAR midiOutAllNotesOff
(
LPDEVICEINFO pClient
);
VOID FAR waveCallback
(
LPDEVICEINFO pWave,
UINT msg,
DWORD_PTR dw1
);
MMRESULT waveOpen
(
LPDEVICEINFO DeviceInfo,
DWORD_PTR dwUser,
LPWAVEOPENDESC pwod,
DWORD dwParam2
);
VOID waveCleanUp
(
LPDEVICEINFO pClient
);
MMRESULT waveWrite
(
LPDEVICEINFO pClient,
LPWAVEHDR pHdr
);
MMRESULT wdmaudSubmitWaveHeader
(
LPDEVICEINFO DeviceInfo,
LPWAVEHDR pHdr
);
MMRESULT FAR wdmaudSubmitMidiOutHeader
(
LPDEVICEINFO DeviceInfo,
LPMIDIHDR pHdr
);
MMRESULT wdmaudSubmitMidiInHeader
(
LPDEVICEINFO DeviceInfo,
LPMIDIHDR pHdrex
);
VOID waveCompleteHeader
(
LPDEVICEINFO DeviceInfo
);
VOID midiInCompleteHeader
(
LPDEVICEINFO DeviceInfo,
DWORD dwTimeStamp,
WORD wDataType
);
VOID midiInEventCallback
(
HANDLE MidiHandle,
DWORD dwEvent
);
#ifdef UNDER_NT
PSECURITY_DESCRIPTOR BuildSecurityDescriptor
(
DWORD AccessMask
);
void DestroySecurityDescriptor
(
PSECURITY_DESCRIPTOR pSd
);
MMRESULT wdmaudPrepareWaveHeader
(
LPDEVICEINFO DeviceInfo,
LPWAVEHDR pHdr
);
MMRESULT wdmaudUnprepareWaveHeader
(
LPDEVICEINFO DeviceInfo,
LPWAVEHDR pHdr
);
MMRESULT wdmaudGetMidiData
(
LPDEVICEINFO DeviceInfo,
LPMIDIDATALISTENTRY pOldMidiDataListEntry
);
void wdmaudParseMidiData
(
LPDEVICEINFO DeviceInfo,
LPMIDIDATALISTENTRY pMidiData
);
void wdmaudFreeMidiData
(
LPDEVICEINFO DeviceInfo,
LPMIDIDATALISTENTRY pMidiData
);
MMRESULT wdmaudFreeMidiQ
(
LPDEVICEINFO DeviceInfo
);
MMRESULT wdmaudCreateCompletionThread
(
LPDEVICEINFO DeviceInfo
);
MMRESULT wdmaudDestroyCompletionThread
(
LPDEVICEINFO DeviceInfo
);
#endif
MMRESULT
IsValidDeviceInfo(
LPDEVICEINFO lpDeviceInfo
);
MMRESULT
IsValidDeviceState(
LPDEVICESTATE lpDeviceState,
BOOL bFullyConfigured
);
MMRESULT
IsValidWaveHeader(
LPWAVEHDR pWaveHdr
);
MMRESULT
IsValidMidiHeader(
LPMIDIHDR pMidiHdr
);
MMRESULT
IsValidPrepareWaveHeader(
PWAVEPREPAREDATA pPrepare
);
BOOL
IsValidDeviceInterface(
LPCWSTR DeviceInterface
);
MMRESULT
IsValidOverLapped(
LPOVERLAPPED lpol
);
MMRESULT
IsValidMidiDataListEntry(
LPMIDIDATALISTENTRY pMidiDataListEntry
);
MMRESULT
IsValidWaveOpenDesc(
LPWAVEOPENDESC pwod
);
#ifdef DEBUG
#define ISVALIDDEVICEINFO(x) IsValidDeviceInfo(x)
#define ISVALIDDEVICESTATE(x,y) IsValidDeviceState(x,y)
#define ISVALIDWAVEHEADER(x) IsValidWaveHeader(x)
#define ISVALIDMIDIHEADER(x) IsValidMidiHeader(x)
#define ISVALIDPREPAREWAVEHEADER(x) IsValidPrepareWaveHeader(x)
#define ISVALIDDEVICEINTERFACE(x) IsValidDeviceInterface(x)
#define ISVALIDOVERLAPPED(x) IsValidOverLapped(x)
#define ISVALIDMIDIDATALISTENTRY(x) IsValidMidiDataListEntry(x)
#define ISVALIDWAVEOPENDESC(x) IsValidWaveOpenDesc(x)
#else
#define ISVALIDDEVICEINFO(x)
#define ISVALIDDEVICESTATE(x,y)
#define ISVALIDWAVEHEADER(x)
#define ISVALIDMIDIHEADER(x)
#define ISVALIDPREPAREWAVEHEADER(x)
#define ISVALIDDEVICEINTERFACE(x)
#define ISVALIDOVERLAPPED(x)
#define ISVALIDMIDIDATALISTENTRY(x)
#define ISVALIDWAVEOPENDESC(x)
#endif
#ifndef UNDER_NT
VOID WaveDeviceCallback();
VOID MidiInDeviceCallback();
VOID MidiEventDeviceCallback();
VOID MixerDeviceCallback();
#endif
PCALLBACKS wdmaGetCallbacks();
PCALLBACKS wdmaCreateCallbacks();
#ifdef __cplusplus
}
#endif