/*************************************************************************** * winmmi.h * * Copyright (c) Microsoft Corporation 1990. All rights reserved * * private include file * * History * * 15 Jan 92 - Robin Speed (RobinSp) and Steve Davies (SteveDav) - * major NT update * 6 Feb 92 - LaurieGr replaced HLOCAL by HANDLE * ***************************************************************************/ /*************************************************************************** Useful include files for winmm component ***************************************************************************/ #define DEBUG_RETAIL /* Parameter checking is IN */ #if DBG #ifndef DEBUG #define DEBUG #endif #endif #ifndef WINMMI_H #define WINMMI_H /* Protect against double inclusion */ #ifndef RC_INVOKED #include #include #endif /* RC_INVOKED */ #include #include "mmsystem.h" /* Pick up the public header */ #include "mmsysp.h" /* pick up the internal definitions */ #include "mmcommon.h" /* pick up the definitions common to the NT project */ #ifndef NODDK #include "mmddk.h" #endif extern BOOL WinmmRunningInWOW; // Are we running in WOW /*--------------------------------------------------------------------*\ * Unicode helper macros \*--------------------------------------------------------------------*/ #define SZCODE CHAR #define WSZCODE WCHAR #define BYTE_GIVEN_CHAR(x) ( (x) * sizeof( WCHAR ) ) #define CHAR_GIVEN_BYTE(x) ( (x) / sizeof( WCHAR ) ) int Iwcstombs(LPSTR lpstr, LPCWSTR lpwstr, int len); int Imbstowcs(LPWSTR lpwstr, LPCSTR lpstr, int len); /*************************************************************************** Definitions to help with common windows code ***************************************************************************/ #define HPSTR LPSTR #ifndef RC_INVOKED /* These are defined to RC */ #define STATICDT #define STATICFN #define STATIC #if DBG extern void InitDebugLevel(void); void mciCheckLocks(void); #undef STATICDT #undef STATICFN #undef STATIC #define STATICDT #define STATICFN #define STATIC #else #define InitDebugLevel() #endif /* DBG */ #endif /* RC_INVOKED */ /************************************************************************** Strings related to INI files **************************************************************************/ /* // File and section names for sound aliases */ #define SOUND_INI_FILE L"win.ini" #define SOUND_SECTION L"Sounds" #define SOUND_DEFAULT L".Default" #define SOUND_RESOURCE_TYPE L"WAVE" // in .rc file extern WSZCODE szSystemDefaultSound[]; // Name of the default sound extern WSZCODE szSoundSection[]; // WIN.INI section for sounds extern WSZCODE wszSystemIni[]; // defined in Winmm.c extern WSZCODE wszDrivers[]; // defined in Winmm.c extern WSZCODE wszNull[]; // defined in Winmm.c #define STR_ALIAS_SYSTEMASTERISK 3000 #define STR_ALIAS_SYSTEMQUESTION 3001 #define STR_ALIAS_SYSTEMHAND 3002 #define STR_ALIAS_SYSTEMEXIT 3003 #define STR_ALIAS_SYSTEMSTART 3004 #define STR_ALIAS_SYSTEMWELCOME 3005 #define STR_ALIAS_SYSTEMEXCLAMATION 3006 #define STR_ALIAS_SYSTEMDEFAULT 3007 #define STR_LABEL_APPGPFAULT 3008 #define STR_LABEL_CLOSE 3009 #define STR_LABEL_EMPTYRECYCLEBIN 3010 #define STR_LABEL_MAXIMIZE 3011 #define STR_LABEL_MENUCOMMAND 3012 #define STR_LABEL_MENUPOPUP 3013 #define STR_LABEL_MINIMIZE 3014 #define STR_LABEL_OPEN 3015 #define STR_LABEL_RESTOREDOWN 3016 #define STR_LABEL_RESTOREUP 3017 #define STR_LABEL_RINGIN 3018 #define STR_LABEL_RINGOUT 3019 #define STR_LABEL_SYSTEMASTERISK 3020 #define STR_LABEL_SYSTEMDEFAULT 3021 #define STR_LABEL_SYSTEMEXCLAMATION 3022 #define STR_LABEL_SYSTEMEXIT 3023 #define STR_LABEL_SYSTEMHAND 3024 #define STR_LABEL_SYSTEMQUESTION 3025 #define STR_LABEL_SYSTEMSTART 3026 #define STR_WINDOWS_APP_NAME 3027 #define STR_EXPLORER_APP_NAME 3028 /* // File and section names for the mci functions */ #define MCIDRIVERS_INI_FILE L"system.ini" #define MCI_HANDLERS MCI_SECTION /*********************************************************************** * * Speed up profile stuff by going straight to the registry * ***********************************************************************/ VOID mmRegFree(VOID); BOOL mmRegCreateUserKey ( LPCWSTR lpszPathName, LPCWSTR lpszKeyName ); BOOL mmRegQueryUserKey ( LPCWSTR lpszKeyName ); BOOL mmRegDeleteUserKey ( LPCWSTR lpszKeyName ); BOOL mmRegSetUserValue ( LPCWSTR lpszSectionName, LPCWSTR lpszValueName, LPCWSTR lpszValue ); BOOL mmRegQueryUserValue ( LPCWSTR lpszSectionName, LPCWSTR lpszValueName, ULONG dwLen, LPWSTR lpszValue ); BOOL mmRegCreateMachineKey ( LPCWSTR lpszPath, LPCWSTR lpszNewKey ); BOOL mmRegSetMachineValue ( LPCWSTR lpszSectionName, LPCWSTR lpszValueName, LPCWSTR lpszValue ); BOOL mmRegQueryMachineValue ( LPCWSTR lpszSectionName, LPCWSTR lpszValueName, ULONG dwLen, LPWSTR lpszValue ); DWORD winmmGetProfileString( LPCWSTR lpAppName, LPCWSTR lpKeyName, LPCWSTR lpDefault, LPWSTR lpReturnedString, DWORD nSize ); DWORD winmmGetPrivateProfileString( LPCWSTR lpSection, LPCWSTR lpKeyName, LPCWSTR lpDefault, LPWSTR lpReturnedString, DWORD nSize, LPCWSTR lpFileName ); /*********************************************************************** * * Used by hwndNotify code * ***********************************************************************/ extern BOOL sndMessage( LPWSTR lszSoundName, UINT wFlags ); extern BOOL InitAsyncSound(VOID); extern CRITICAL_SECTION WavHdrCritSec; extern CRITICAL_SECTION SoundCritSec; extern CRITICAL_SECTION mciGlobalCritSec; extern CRITICAL_SECTION midiStrmHdrCritSec; /*********************************************************************** * * Flag deduced by initialization to special case running in the server * ***********************************************************************/ extern BOOL WinmmRunningInServer; // Are we running in the user/base server? /*********************************************************************** * * prototypes from "winmm.c" * ***********************************************************************/ void WaveMapperInit(void); void MidiMapperInit(void); void midiEmulatorInit(void); /*********************************************************************** * * prototypes from "mmiomisc.c" * ***********************************************************************/ PBYTE AsciiStrToUnicodeStr( PBYTE pdst, PBYTE pmax, LPCSTR psrc ); PBYTE UnicodeStrToAsciiStr( PBYTE pdst, PBYTE pmax, LPCWSTR psrc); LPWSTR AllocUnicodeStr( LPCSTR lpSourceStr ); BOOL FreeUnicodeStr( LPWSTR lpStr ); LPSTR AllocAsciiStr( LPCWSTR lpSourceStr ); BOOL FreeAsciiStr( LPSTR lpStr ); /*********************************************************************** * * prototypes from "mmio.c" * ***********************************************************************/ void mmioCleanupIOProcs(HANDLE hTask); /*********************************************************************** * * Timer functions * ***********************************************************************/ #ifndef MMNOTIMER BOOL TimeInit(void); void TimeCleanup(DWORD ThreadId); UINT timeSetEventInternal(UINT wDelay, UINT wResolution, LPTIMECALLBACK lpFunction, DWORD dwUser, UINT wFlags, BOOL IsWOW); #endif // !MMNOTIMER /*********************************************************************** * * Information structure used to play sounds * ***********************************************************************/ #define PLAY_NAME_SIZE 256 typedef struct _PLAY_INFO { HANDLE hModule; HANDLE hRequestingTask; // Handle of thread that requested sound DWORD dwFlags; WCHAR szName[1]; // the structure will be allocated large enough for the name } PLAY_INFO, *PPLAY_INFO; #define WAIT_FOREVER ((DWORD)(-1)) /*************************************************************************** global data ***************************************************************************/ extern HANDLE ghInst; HANDLE hHeap; /*************************************************************************** * * Define the product version to be returned from * mmsystemgetversion and any other messagebox or * API that needs the public product version. * ***************************************************************************/ #define MMSYSTEM_VERSION 0X030A typedef UINT MMMESSAGE; // Multi media message type (internal) #ifndef WM_MM_RESERVED_FIRST // Copy constants from winuserp.h #define WM_MM_RESERVED_FIRST 0x03A0 #define WM_MM_RESERVED_LAST 0x03DF #endif #define MM_POLYMSGBUFRDONE (WM_MM_RESERVED_FIRST+0x2B) #define MM_SND_PLAY (WM_MM_RESERVED_FIRST+0x2C) #define MM_SND_ABORT (WM_MM_RESERVED_FIRST+0x2D) #define MM_SND_SEND (WM_MM_RESERVED_FIRST+0x2E) #define MM_SND_WAIT (WM_MM_RESERVED_FIRST+0x2F) #define MCIWAITMSG (MM_SND_WAIT) #if MM_SND_WAIT > WM_MM_RESERVED_LAST #error "MM_SND_WAIT is defined beyond the reserved WM_MM range" #endif /*************************************************************************** DEBUGGING SUPPORT ***************************************************************************/ #if DBG #ifdef DEBUGLEVELVAR // So that other WINMM related modules can use their own debug level // variable #define winmmDebugLevel DEBUGLEVELVAR #endif extern int winmmDebugLevel; extern void winmmDbgOut(LPSTR lpszFormat, ...); extern void dDbgAssert(LPSTR exp, LPSTR file, int line); DWORD __dwEval; extern void winmmDbgOut(LPSTR lpszFormat, ...); #define dprintf( _x_ ) winmmDbgOut _x_ #define dprintf1( _x_ ) if (winmmDebugLevel >= 1) winmmDbgOut _x_ #define dprintf2( _x_ ) if (winmmDebugLevel >= 2) winmmDbgOut _x_ #define dprintf3( _x_ ) if (winmmDebugLevel >= 3) winmmDbgOut _x_ #define dprintf4( _x_ ) if (winmmDebugLevel >= 4) winmmDbgOut _x_ #define dprintf5( _x_ ) if (winmmDebugLevel >= 5) winmmDbgOut _x_ #define dprintf6( _x_ ) if (winmmDebugLevel >= 6) winmmDbgOut _x_ #define WinAssert(exp) \ ((exp) ? (void)0 : dDbgAssert(#exp, __FILE__, __LINE__)) #define WinEval(exp) \ ((__dwEval=(DWORD)(exp)), \ __dwEval ? (void)0 : dDbgAssert(#exp, __FILE__, __LINE__), __dwEval) #define DOUT(x) (OutputDebugStringA x, 0) // #define DOUTX(x) (OutputDebugStringA x, 0) // #define ROUTS(x) (OutputDebugStringA(x), OutputDebugStringA("\r\n"), 0) #define ROUTSW(x) (OutputDebugStringW x, OutputDebugStringW(L"\r\n"), 0) #define ROUT(x) (OutputDebugStringA x, OutputDebugStringA("\r\n"), 0) // #define ROUTX(x) (OutputDebugStringA(x), 0) #else #define dprintf(x) #define dprintf1(x) #define dprintf2(x) #define dprintf3(x) #define dprintf4(x) #define dprintf5(x) #define dprintf6(x) #define WinAssert(exp) 0 #define WinEval(exp) (exp) #define DOUT(x) 0 // #define DOUTX(x) 0 // #define ROUTS(x) 0 #define ROUT(x) 0 // #define ROUTX(x) 0 #endif /*************************************************************************** Resource IDs ***************************************************************************/ #define IDS_TASKSTUB 2000 #define STR_MCIUNKNOWN 2001 /* "Unknown error returned from MCI command" */ // #define STR_WAVEINPUT 2004 // #define STR_WAVEOUTPUT 2005 // #define STR_MIDIINPUT 2006 // #define STR_MIDIOUTPUT 2007 #define STR_MCISSERRTXT 2009 #define STR_MCISCERRTXT 2010 #define STR_MIDIMAPPER 2011 #define STR_DRIVERS 2012 #define STR_SYSTEMINI 2013 #define STR_BOOT 2014 /*************************************************************************** Memory allocation using our local heap ***************************************************************************/ HANDLE hHeap; PVOID winmmAlloc(DWORD cb); PVOID winmmReAlloc(PVOID ptr, DWORD cb); #define winmmFree(ptr) HeapFree(hHeap, 0, (ptr)) /*************************************************************************** LOCKING AND UNLOCKING MEMORY ***************************************************************************/ #if 0 BOOL HugePageLock(LPVOID lpArea, DWORD dwLength); void HugePageUnlock(LPVOID lpArea, DWORD dwLength); #else #define HugePageLock(lpArea, dwLength) (TRUE) #define HugePageUnlock(lpArea, dwLength) #endif /**************************************************************************** API to install/remove/query a MMSYS driver ****************************************************************************/ /* generic prototype for audio device driver entry-point functions // midMessage(), modMessage(), widMessage(), wodMessage(), auxMessage() */ typedef DWORD (APIENTRY *DRIVERMSGPROC)(DWORD, DWORD, DWORD, DWORD, DWORD); UINT APIENTRY mmDrvInstall(HANDLE hDriver, WCHAR * wszDrvEntry, DRIVERMSGPROC drvMessage, UINT wFlags); /* @doc INTERNAL MMSYSTEM @type UINT | HMD | This type definition specifies a handle to media resource entry. This can be used as a unique identifier when specifying a media resource. */ DECLARE_HANDLE(HMD); BOOL FAR PASCAL mregHandleInternalMessages (LPVOID pmd, DWORD dwType, DWORD dwMap, UINT msg, DWORD dw1, DWORD dw2, MMRESULT * pmmr); DWORD FAR PASCAL mregDriverInformation(UINT uDeviceID, WORD fwClass, UINT uMessage, DWORD dwParam1, DWORD dwParam2); UINT FAR PASCAL mregIncUsage(HMD hmd); UINT FAR PASCAL mregDecUsage(HMD hmd); MMRESULT FAR PASCAL mregFindDevice(UINT uDeviceID, WORD fwFindDevice, HMD FAR* phmd, UINT FAR* puDevicePort); /***************************************************************************** Driver stuff - BUGBUG this will change when we work out the real installable driver story on NT ****************************************************************************/ LONG DrvClose(HANDLE hDriver, LONG lParam1, LONG lParam2); HANDLE DrvOpen(LPCWSTR szDriverName, LPCWSTR szSectionName, LONG lParam2); LONG DrvSendMessage(HANDLE hDriver, UINT message, LONG lParam1, LONG lParam2); //HMODULE APIENTRY DrvGetModuleHandle(HDRVR hDriver); typedef DWORD (DRVPROC)(HANDLE hDriver, UINT msg, LONG lp1, LONG lp2); typedef DRVPROC *LPDRVPROC; // // Initialize Joystick code // BOOL JoyInit(void); /* ** Special function for creating threads inside the server process (we only ** use this to create the thread for playing sounds) */ BOOLEAN CreateServerPlayingThread(PVOID ThreadStartRoutine); /* // exclude some stuff if MMDDK.H is not included */ #ifdef MMDDKINC /* use this to test for MMDDK.H */ // // note this must be the same as MIDIDRV/WAVEDRV/AUXDRV // typedef struct { HANDLE hDriver; /* handle to the module */ DRIVERMSGPROC drvMessage; /* pointer to entry point */ BYTE bNumDevs; /* number of devices supported */ BYTE bUsage; /* usage count (number of handle's open) */ WCHAR wszDrvEntry[64]; /* driver filename */ } MMDRV, *PMMDRV; #ifndef MMNOMIDI /**************************************************************************** Clock routines used by MIDI. These routines provide clocks which run at the current tempo or SMPTE rate based on timeGetTime(). ****************************************************************************/ typedef DWORD MILLISECS; typedef long TICKS; #define CLK_CS_PAUSED 0x00000001L #define CLK_CS_RUNNING 0x00000002L #define CLK_TK_NOW ((TICKS)-1L) // // This structure is allocated by the client (probably in a handle structure) // in MMSYSTEM's DS and passed as a near pointer. // typedef struct tag_clock *PCLOCK; typedef DWORD (FAR PASCAL *CLK_TIMEBASE)(PCLOCK); typedef struct tag_clock { MILLISECS msPrev; TICKS tkPrev; MILLISECS msT0; DWORD dwNum; DWORD dwDenom; DWORD dwState; CLK_TIMEBASE fnTimebase; } CLOCK; void FAR PASCAL clockInit(PCLOCK pclock, MILLISECS msPrev, TICKS tkPrev, CLK_TIMEBASE fnTimebase); void FAR PASCAL clockSetRate(PCLOCK pclock, TICKS tkWhen, DWORD dwNum, DWORD dwDenom); void FAR PASCAL clockPause(PCLOCK pclock, TICKS tkWhen); void FAR PASCAL clockRestart(PCLOCK pclock, TICKS tkWhen, MILLISECS msWhen); TICKS FAR PASCAL clockTime(PCLOCK pclock); MILLISECS FAR PASCAL clockMsTime(PCLOCK pclock); MILLISECS FAR PASCAL clockOffsetTo(PCLOCK pclock, TICKS tkWhen); /**************************************************************************** Macros and prototypes shared by the MIDI subsystem. ****************************************************************************/ // #pragma message() with file/line numbers! // #define __PRAGMSG(l,x,c) message(__FILE__"("#l") : "c": "x) #define _WARN(l,x) __PRAGMSG(l,x, "warning") #define WARNMSG(x) _WARN(__LINE__,x) #define _FIX(l,x) __PRAGMSG(l,x, "fix") #define FIXMSG(x) _FIX(__LINE__,x) #define DEFAULT_TEMPO 500000L // 500,000 uSec/qn == 120 BPM #define DEFAULT_TIMEDIV 24 // 24 ticks per quarter note #define DEFAULT_CBTIMEOUT 100 // 100 milliseconds #define PM_STATE_READY 0 // polymsg ready to play #define PM_STATE_BLOCKED 1 // Blocked on outgoing SysEx #define PM_STATE_EMPTY 2 // No polymsg queued #define PM_STATE_STOPPED 3 // Just opened/reset/stopped // No polymsg sent yet. #define PM_STATE_PAUSED 4 // Paused at some position #define MIN_PERIOD 1 // millisecs of timer resolution // // Macros for dealing with time division dword // #define IS_SMPTE 0x00008000L #define METER_NUM(dw) (UINT)((HIWORD(dw)>>8)&0x00FF) #define METER_DENOM(dw) (UINT)(HIWORD(dw)&0x00FF) #define TICKS_PER_QN(dw) (UINT)((dw)&0x7FFF) #define SMPTE_FORMAT(dw) (((int)((dw)&0xFF00))>>8) #define TICKS_PER_FRAME(dw) (UINT)((dw)&0x00FF) // // Constants for 30-Drop format conversion // #define S30D_FRAMES_PER_10MIN 17982 #define S30D_FRAMES_PER_MIN 1798 // // SMPTE formats from MIDI file time division // #define SMPTE_24 24 #define SMPTE_25 25 #define SMPTE_30DROP 29 #define SMPTE_30 30 // // Stuff that's part of MIDI spec // #define MIDI_NOTEOFF (BYTE)(0x80) #define MIDI_NOTEON (BYTE)(0x90) #define MIDI_CONTROLCHANGE (BYTE)(0xB0) #define MIDI_SYSEX (BYTE)(0xF0) #define MIDI_TIMING_CLK (BYTE)(0xF8) #define MIDI_SUSTAIN (BYTE)(0x40) // w/ MIDI_CONTROLCHANGE // // Indices into dwReserved[] fields of struct // // 0,1,2 -- MMSYSTEM (core, emulator) // 3,4,5 -- MIDI mapper // 6,7 -- DDK (3rd party drivers) #define MH_REFCNT 0 // MMSYSTEM core (stream header only) #define MH_PARENT 0 // MMSYSTEM core (shadow header only) #define MH_STREAM 0 // Emulator (long msg header only) #define MH_SHADOW 1 // MMSYSTEM core (stream header only) #define MH_BUFIDX 1 // Emulator (shadow header only) #define MH_STRMPME 2 // Emulator (shadow header, long msg header) /***************************************************************************** * * @doc INTERNAL MIDI * * @types MIDIDRV | This structure contains all of the information about an * open or handle. * * @field HMD | hmd | * Handle to media device for this driver. * * @field UINT | uDevice | * Index of this device off of HMD (subunit number relative to this driver). * * @field DRIVERMSGPROC | drvMessage | * Pointer to the associated driver entry point. * * @field DWORD | dwDrvUser | * Driver user DWORD; used by driver to differentiate open instance. Set * by driver on OPEN message; passed back to driver on every call. * * @field PMIDIDRV | pdevNext | * Specifies the next handle in the linked list of open handles. * (Only kept for handles. * * @field UINT | uLockCount | * Semaphore to serialize access to the handle structure between API calls * and interrupt callbacks. * * @field DWORD | dwTimeDiv | * The time division setting that is active right now during polymsg playback * on this handle. The format is the same as described for * . * * @field DWORD | dwTempo | * Current tempo for polymsg out in microseconds per quarter note (as in the * Standard MIDI File specification). * * @field DWORD | dwPolyMsgState | * The current state of polymsg playback for emulation. * @flag PM_STATE_READY | Events may be played and are waiting. * @flag PM_STATE_BLOCKED | Driver is busy sending SysEx; don't play anything * else. * @flag PM_STATE_EMPTY | Not busy but nothing else in the queue to play. * @flag PM_STATE_PAUSED | Device has been paused with . * * @field DWORD | dwSavedState | * If the device is paused, this field will contain the state to be * restored when restart occurs. * * @field LPMIDIHDR | lpmhFront | * Front of queue of MIDIHDR's waiting to be played via polymsg in/out. The * header pointed to by this field is the header currently being played/ * recorded. * * @field LPMIDIHDR | lpmhRear | * End of MIDIHDR queue. Buffers are inserted from the app here. * * @field DWORD | dwCallback | * Address of user callback. * * @field DWORD | dwFlags | * User-supplied callback flags. * * @field BOOL | fEmulate | * TRUE if we are emulating polymsg in/out. * * @field BOOL | fReset | * TRUE if we're in the middle of a MIDM_RESET. Checked to see if we should * give our shadow buffers back to the driver or retain them for cleanup. * * @field BOOL | fStarted | * TRUE if MIDI input has been started. * * @field UINT | uCBTimeout | * Time in milliseconds that a buffer can be help in MIDI input w/o being * called back. * * @field UINT | uCBTimer | * Timer ID of the timer which is being used to determine if a MIDI * input buffer has been queued for too long. * * @field DWORD | dwInputBuffers | * The maximum number of input buffers that have been prepared on this handle. * Used for calculating shadow buffer pool. * * @field DWORD | cbInputBuffers | * The maximum size of input buffer which has been prepared on this handle. * Used for calculating shadow buffer pool. * * @field DWORD | dwShadowBuffers | * The current number of shadow buffers allocated on this handle. * * @field CLOCK | clock | * Clock maintained by the clock API's for timebase of both output and * input emulation. * * @field DWORD | tkNextEventDue | Tick time of the next event due * on polymsg emulation. * * @field TICKS | tkTimeOfLastEvent | Tick time that emulator sent the * last event. * * @field DWORD | tkPlayed | Total ticks played on stream. * * @field DWORD | tkTime | Tick position in stream now. * * @field DWORD | dwTimebase | Flag indicating where timebase is coming * from. May be one of: * @flag MIDI_TBF_INTERNAL | Timebase is * @flag MIDI_TBF_MIDICLK | Timebase is MIDI input clocks. * * @field BYTE | rbNoteOn[] | Array of note-on counts per-channel per-note. * Only allocated for output handles which are doing COOKED mode emulation. * *****************************************************************************/ #define ELESIZE(t,e) (sizeof(((t*)NULL)->e)) //#define MDV_F_EXPANDSTATUS 0x00000001L #define MDV_F_EMULATE 0x00000002L #define MDV_F_RESET 0x00000004L #define MDV_F_STARTED 0x00000008L #define MDV_F_ZOMBIE 0x00000010L #define MDV_F_SENDING 0x00000020L #define MDV_F_OWNED 0x00000040L #define MDV_F_LOCKED 0x00000080L #define MEM_MAX_LATENESS 64 typedef MMDRV MIDIDRV, *PMIDIDRV; typedef struct midistrm_tag *PMIDISTRM; typedef struct mididev_tag *PMIDIDEV; typedef struct midiemu_tag *PMIDIEMU; typedef struct mididev_tag { PMIDIDRV mididrv; UINT wDevice; DWORD dwDrvUser; UINT uDeviceID; PMIDIDEV pmThru; /* pointer to midi thru device */ PMIDIEMU pme; /* Iff owned by emulator */ } MIDIDEV; typedef MIDIDEV *PMIDIDEV; extern MIDIDRV midioutdrv[MAXMIDIDRIVERS+1]; /* output device driver list */ extern MIDIDRV midiindrv[MAXMIDIDRIVERS+1]; /* input device driver list */ extern UINT wTotalMidiOutDevs; /* total midi output devices */ extern UINT wTotalMidiInDevs; /* total midi input devices */ typedef struct midiemusid_tag { DWORD dwStreamID; HMIDI hMidi; } MIDIEMUSID, *PMIDIEMUSID; typedef struct midiemu_tag { PMIDIEMU pNext; HMIDISTRM hStream; DWORD fdwDev; LONG lLockCount; // Must be 32-bit aligned CRITICAL_SECTION CritSec; // Serialize access DWORD dwSignature; // Cookie to keep track of validity DWORD dwTimeDiv; // Time division in use right now DWORD dwTempo; // Current tempo DWORD dwPolyMsgState; // Ready or blocked on SysEx DWORD dwSavedState; // State saved when paused LPMIDIHDR lpmhFront ; // Front of PolyMsg queue LPMIDIHDR lpmhRear ; // Rear of PolyMsg queue DWORD dwCallback; // User callback DWORD dwFlags; // User callback flags DWORD dwInstance; DWORD dwSupport; // From MODM_GETDEVCAPS BYTE bRunningStatus; // Track running status // // Rewrite midiOutPolyMsg timekeeping - new stuff!!! // CLOCK clock; TICKS tkNextEventDue; // Tick time of next event TICKS tkTimeOfLastEvent; // Tick time of last received event TICKS tkPlayed; // Cumulative ticks played so far TICKS tkTime; // Tick position in stream *NOW* LPBYTE rbNoteOn; // Count of notes on per channel per note UINT cSentLongMsgs; // Oustanding long messages UINT chMidi; // # Stream ID's UINT cPostedBuffers; // Posted to mmtask for cleanup #ifdef DEBUG DWORD cEvents; UINT auLateness[MEM_MAX_LATENESS]; // 0..64 milliseconds late #endif MIDIEMUSID rIds[]; // HMIDI's indexed by stream ID } MIDIEMU; #define MSI_F_EMULATOR 0x00000001L #define MSI_F_FIRST 0x00000002L #define MSI_F_OPENED 0x00000004L #define MSE_SIGNATURE 0x12341234L typedef struct midistrmid_tag { HMD hmd; UINT uDevice; DRIVERMSGPROC drvMessage; DWORD dwDrvUser; DWORD fdwId; CRITICAL_SECTION CritSec; } MIDISTRMID, *PMIDISTRMID; #define MDS_F_STOPPING 0x00000001L typedef struct midistrm_tag { DWORD fdwOpen; DWORD fdwStrm; DWORD dwCallback; DWORD dwInstance; LPMIDIHDR lpmhFront; LPMIDIHDR lpmhRear; DWORD cDrvrs; // # unique drivers in rgIds[] DWORD cIds; MIDISTRMID rgIds[]; } MIDISTRM; /***************************************************************************** * * @doc INTERNAL MIDI * * @types MIDIHDREXT | * This structure is allocated by and is pointed to by the * field of the associated . It contains information * about what embedded long messages are in the polymsg buffer described * by the MIDIHDR. * * The is followed by multiple structures, also * allocated by , which describe each of the embedded * long messages which need to be played. * * @field DWORD | dwTimeDivision | * The time division specified with to play this buffer * with. * * @field UINT | nHeaders | * The number of structures which follow the end of this * . * * @field LPMIDIHDR | lpmidihdr | * Pointer to the next structure due to be played. * * *****************************************************************************/ typedef struct midihdrext_tag { UINT nHeaders ; LPMIDIHDR lpmidihdr ; } MIDIHDREXT, FAR *LPMIDIHDREXT ; extern HANDLE g_hClosepme; /* * Internal prototypes for MIDI */ extern STATIC DWORD MapMidiId(PMIDIDRV mididrv, UINT wTotalNumDevs, UINT id); extern BOOL FAR PASCAL midiLockPageable(void); extern void NEAR PASCAL midiUnlockPageable(void); extern MMRESULT NEAR PASCAL midiPrepareHeader(LPMIDIHDR lpMidiHdr, UINT wSize); extern MMRESULT NEAR PASCAL midiUnprepareHeader(LPMIDIHDR lpMidiHdr, UINT wSize); extern STATIC MMRESULT midiMessage(HMIDI hMidi, UINT msg, DWORD dwP1, DWORD dwP2); extern DWORD FAR PASCAL midiStreamMessage(PMIDISTRMID pmsi, UINT msg, DWORD dwP1, DWORD dwP2); extern DWORD FAR PASCAL midiStreamBroadcast(PMIDISTRM pms, UINT msg, DWORD dwP1, DWORD dwP2); extern STATIC MMRESULT midiIDMessage(PMIDIDRV mididrv, UINT wTotalNumDevs, UINT uDeviceID, UINT wMessage, DWORD dwParam1, DWORD dwParam2); extern MMRESULT NEAR PASCAL midiGetPosition(PMIDISTRM pms, LPMMTIME pmmt, UINT cbmmt); extern MMRESULT NEAR PASCAL midiGetErrorText(MMRESULT wError, LPSTR lpText, UINT wSize); extern MMRESULT WINAPI midiOutGetID(HMIDIOUT hMidiOut, UINT FAR* lpuDeviceID); extern MMRESULT FAR PASCAL mseOutSend(PMIDIEMU pme, LPMIDIHDR lpMidiHdr, UINT cbMidiHdr); extern void FAR PASCAL midiOutSetClockRate(PMIDIEMU pme, TICKS tkWhen); extern BOOL NEAR PASCAL midiOutScheduleNextEvent(PMIDIEMU pme); #ifdef DEBUG extern void NEAR PASCAL midiOutPlayNextPolyEvent(PMIDIEMU pme, DWORD dwStartTime); #else extern void NEAR PASCAL midiOutPlayNextPolyEvent(PMIDIEMU pme); #endif extern void NEAR PASCAL midiOutDequeueAndCallback(PMIDIEMU pme); extern void FAR PASCAL midiOutNukePMBuffer(PMIDIEMU pme, LPMIDIHDR lpmh); extern void CALLBACK midiOutTimerTick(UINT uTimerID, UINT wMsg, DWORD dwUser, DWORD dw1, DWORD dw2); extern void CALLBACK midiOutCallback(HMIDIOUT hMidiOut, WORD wMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2); extern void NEAR PASCAL midiOutAllNotesOff(PMIDIEMU pme); extern void CALLBACK midiOutStreamCallback(HMIDISTRM hMidiOut, WORD wMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2); extern MMRESULT midiInSetThru (HMIDI hmi, HMIDIOUT hmo, BOOL bAdd); // mseXXX - MIDI Stream Emulator // extern DWORD FAR PASCAL mseMessage(UINT msg, DWORD dwUser, DWORD dwParam1, DWORD dwParam2); #endif /* ifndef MMNOMIDI */ #ifndef MMNOWAVE typedef MMDRV WAVEDRV, *PWAVEDRV; extern WAVEDRV waveoutdrv[MAXWAVEDRIVERS+1]; /* output device driver list */ extern WAVEDRV waveindrv[MAXWAVEDRIVERS+1]; /* input device driver list */ extern UINT wTotalWaveOutDevs; /* total wave output devices */ extern UINT wTotalWaveInDevs; /* total wave input devices */ extern STATIC DWORD MapWaveId(PWAVEDRV wavedrv, UINT wTotalNumDevs, UINT id); #endif /*ifndef MMNOWAVE */ #ifndef MMNOAUX typedef MMDRV AUXDRV, *PAUXDRV; extern AUXDRV auxdrv[MAXAUXDRIVERS+1]; /* auxiliary device driver list */ extern UINT wTotalAuxDevs; /* total auxiliary output devices */ extern STATIC DWORD MapAuxId(UINT id); #endif /* ifndef MMNOAUX */ #ifdef DEBUG_RETAIL extern BYTE fIdReverse; #endif /* ifdef DEBUG_RETAIL */ #endif //ifdef MMDDKINC /**************************************************************************** handle apis's ****************************************************************************/ /* // all MMSYSTEM handles are tagged with the following structure. // // a MMSYSTEM handle is really a fixed local memory object. // // the functions NewHandle() and FreeHandle() create and release a MMSYSTEM // handle. // */ typedef struct tagHNDL { struct tagHNDL *pNext; // link to next handle UINT uType; // type of handle wave, midi, mmio, ... HANDLE hThread; // task that owns it UINT h16; // Corresponding WOW handle CRITICAL_SECTION CritSec; // Serialize access } HNDL, *PHNDL; /*************************************************************************/ #define HtoPH(h) ((PHNDL)(h)-1) #define PHtoH(ph) ((ph) ? (HANDLE)((PHNDL)(ph)+1) : 0) #define HtoPT(t,h) ((t)(h)) #define PTtoH(t,pt) ((t)(pt)) // // Handles can be tested for ownership and reserved at the same time // #define ENTER_MM_HANDLE(h) (EnterCriticalSection(&HtoPH(h)->CritSec)) #define LEAVE_MM_HANDLE(h) ((void)LeaveCriticalSection(&HtoPH(h)->CritSec)) /* // all wave and midi handles will be linked into // a global list, so we can enumerate them latter if needed. // // all handle structures start with a HNDL structure, that contain common fields // // pHandleList points to the first handle in the list // // HandleListCritSec protects the handle list // // the NewHandle() and FreeHandle() functions are used to add/remove // a handle to/from the list */ PHNDL pHandleList; CRITICAL_SECTION HandleListCritSec; extern HANDLE NewHandle(UINT uType, UINT size); extern void FreeHandle(HANDLE h); #define GetHandleType(h) (HtoPH(h)->uType) #define GetHandleOwner(h) (HtoPH(h)->hThread) #define GetHandleFirst() (PHtoH(pHandleList)) #define GetHandleNext(h) (PHtoH(HtoPH(h)->pNext)) #define SetHandleOwner(h,hOwn) (HtoPH(h)->hThread = (hOwn)) #define GetWOWHandle(h) (HtoPH(h)->h16) #define SetWOWHandle(h, myh16) (HtoPH(h)->h16 = (myh16)) /************************************************************************** Test whether the current process is the WOW process. This is not a very nice test to have to make but it's the best we can think of until the WOW people come up with a proper call **************************************************************************/ #define IS_WOW_PROCESS (NULL != GetModuleHandleW(L"WOW32.DLL")) /**************************************************************************** user debug support ****************************************************************************/ #define DebugErr(x,y) /* BUGBUG - put in error logging later */ #define DebugErr1(flags, sz, a) #ifdef DEBUG_RETAIL #define MM_GET_DEBUG DRV_USER #define MM_GET_DEBUGOUT DRV_USER+1 #define MM_SET_DEBUGOUT DRV_USER+2 #define MM_GET_MCI_DEBUG DRV_USER+3 #define MM_SET_MCI_DEBUG DRV_USER+4 #define MM_GET_MM_DEBUG DRV_USER+5 #define MM_SET_MM_DEBUG DRV_USER+6 #define MM_HINFO_NEXT DRV_USER+10 #define MM_HINFO_TASK DRV_USER+11 #define MM_HINFO_TYPE DRV_USER+12 #define MM_HINFO_MCI DRV_USER+20 #define MM_DRV_RESTART DRV_USER+30 /* // these validation routines can be found in DEBUG.C */ // The kernel validation is turned OFF because it appeared to test every page // before use and this took over a minute for soundrec with a 10MB buffer // //#define USE_KERNEL_VALIDATION #ifdef USE_KERNEL_VALIDATION #define ValidateReadPointer(p, len) (!IsBadReadPtr(p, len)) #define ValidateWritePointer(p, len) (!IsBadWritePtr(p, len)) #define ValidateString(lsz, max_len) (!IsBadStringPtrA(lsz, max_len)) #define ValidateStringW(lsz, max_len) (!IsBadStringPtrW(lsz, max_len)) #else BOOL ValidateReadPointer(LPVOID p, DWORD len); BOOL ValidateWritePointer(LPVOID p, DWORD len); BOOL ValidateString(LPCSTR lsz, DWORD max_len); BOOL ValidateStringW(LPCWSTR lsz, DWORD max_len); #endif // USE_KERNEL_VALIDATION BOOL ValidateHandle(HANDLE h, UINT uType); BOOL ValidateHeader(LPVOID p, UINT uSize, UINT uType); BOOL ValidateCallbackType(DWORD dwCallback, UINT uType); /******************************************************************** * When time permits we should change to using the Kernel supplied and * supported validation routines: * * BOOL WINAPI IsBadReadPtr(CONST VOID *lp, UINT ucb ); * BOOL WINAPI IsBadWritePtr(LPVOID lp, UINT ucb ); * BOOL WINAPI IsBadHugeReadPtr(CONST VOID *lp, UINT ucb); * BOOL WINAPI IsBadHugeWritePtr(LPVOID lp, UINT ucb); * BOOL WINAPI IsBadCodePtr(FARPROC lpfn); * BOOL WINAPI IsBadStringPtrA(LPCSTR lpsz, UINT ucchMax); * BOOL WINAPI IsBadStringPtrW(LPCWSTR lpsz, UINT ucchMax); * * These routines can be found in * \nt\private\WINDOWS\BASE\CLIENT\PROCESS.C * ********************************************************************/ #define V_HANDLE(h, t, r) { if (!ValidateHandle(h, t)) return (r); } #define BAD_HANDLE(h, t) ( !(ValidateHandle((h), (t))) ) #define V_HEADER(p, w, t, r) { if (!ValidateHeader((p), (w), (t))) return (r); } #define V_RPOINTER(p, l, r) { if (!ValidateReadPointer((PVOID)(p), (l))) return (r); } #define V_RPOINTER0(p, l, r) { if ((p) && !ValidateReadPointer((PVOID)(p), (l))) return (r); } #define V_WPOINTER(p, l, r) { if (!ValidateWritePointer((PVOID)(p), (l))) return (r); } #define V_WPOINTER0(p, l, r) { if ((p) && !ValidateWritePointer((PVOID)(p), (l))) return (r); } #define V_DCALLBACK(d, w, r) { if ((d) && !ValidateCallbackType((d), (w))) return(r); } //#define V_DCALLBACK(d, w, r) 0 #define V_TCALLBACK(d, r) 0 #define V_CALLBACK(f, r) { if (IsBadCodePtr((f))) return (r); } #define V_CALLBACK0(f, r) { if ((f) && IsBadCodePtr((f))) return (r); } #define V_STRING(s, l, r) { if (!ValidateString(s,l)) return (r); } #define V_STRING_W(s, l, r) { if (!ValidateStringW(s,l)) return (r); } #define V_FLAGS(t, b, f, r) { if ((t) & ~(b)) { return (r); }} #define V_DFLAGS(t, b, f, r) { if ((t) & ~(b)) {/* LogParamError(ERR_BAD_DFLAGS, (FARPROC)(f), (LPVOID)(DWORD)(t));*/ return (r); }} #define V_MMSYSERR(e, f, t, r) { /* LogParamError(e, (FARPROC)(f), (LPVOID)(DWORD)(t));*/ return (r); } #else /*ifdef DEBUG_RETAIL */ #define V_HANDLE(h, t, r) { if (!(h)) return (r); } #define BAD_HANDLE(h, t) ( !(ValidateHandle((h), (t))) ) #define V_HEADER(p, w, t, r) { if (!(p)) return (r); } #define V_RPOINTER(p, l, r) { if (!(p)) return (r); } #define V_RPOINTER0(p, l, r) 0 #define V_WPOINTER(p, l, r) { if (!(p)) return (r); } #define V_WPOINTER0(p, l, r) 0 #define V_DCALLBACK(d, w, r) { if ((d) && !ValidateCallbackType((d), (w))) return(r); } //#define V_DCALLBACK(d, w, r) 0 #define V_TCALLBACK(d, r) 0 #define V_CALLBACK(f, r) { if (IsBadCodePtr((f))) return (r); } #define V_CALLBACK0(f, r) { if ((f) && IsBadCodePtr((f))) return (r); } //#define V_CALLBACK(f, r) { if (!(f)) return (r); } #define V_CALLBACK0(f, r) 0 #define V_STRING(s, l, r) { if (!(s)) return (r); } #define V_STRING_W(s, l, r) { if (!(s)) return (r); } #define V_FLAGS(t, b, f, r) 0 #define V_DFLAGS(t, b, f, r) { if ((t) & ~(b)) return (r); } #define V_MMSYSERR(e, f, t, r) { return (r); } #endif /* ifdef DEBUG_RETAIL */ /************************************************************************** // //**************************************************************************/ #define TYPE_UNKNOWN 0 #define TYPE_WAVEOUT 1 #define TYPE_WAVEIN 2 #define TYPE_MIDIOUT 3 #define TYPE_MIDIIN 4 #define TYPE_MMIO 5 #define TYPE_MCI 6 #define TYPE_DRVR 7 #define TYPE_MIXER 8 #define TYPE_MIDISTRM 9 #define TYPE_AUX 10 /**************************************************************************/ /**************************************************************************** RIFF constants used to access wave files ****************************************************************************/ #define FOURCC_FMT mmioFOURCC('f', 'm', 't', ' ') #define FOURCC_DATA mmioFOURCC('d', 'a', 't', 'a') #define FOURCC_WAVE mmioFOURCC('W', 'A', 'V', 'E') extern HWND hwndNotify; void FAR PASCAL WaveOutNotify(DWORD wParam, LONG lParam); // in PLAYWAV.C /* // Things not in Win32 */ #define GetCurrentTask() ((HANDLE)GetCurrentThreadId()) /* // other stuff */ // Maximum length, including the terminating NULL, of an Scheme entry. // #define SCH_TYPE_MAX_LENGTH 64 // Maximum length, including the terminating NULL, of an Event entry. // #define EVT_TYPE_MAX_LENGTH 32 // Maximum length, including the terminating NULL, of an App entry. // #define APP_TYPE_MAX_LENGTH 64 // Sound event names can be a fully qualified filepath with a NULL // terminator. // #define MAX_SOUND_NAME_CHARS 144 // sound atom names are composed of: // <1 char id> // // <1 char sep> // // #define MAX_SOUND_ATOM_CHARS (1 + 40 + 1 + MAX_SOUND_NAME_CHARS) #if 0 #undef hmemcpy #define hmemcpy CopyMemory #endif #endif /* WINMMI_H */