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.

1447 lines
48 KiB

  1. /***************************************************************************
  2. * winmmi.h
  3. *
  4. * Copyright (c) 1990-2001 Microsoft Corporation
  5. *
  6. * private include file
  7. *
  8. * History
  9. *
  10. * 15 Jan 92 - Robin Speed (RobinSp) and Steve Davies (SteveDav) -
  11. * major NT update
  12. * 6 Feb 92 - LaurieGr replaced HLOCAL by HANDLE
  13. *
  14. ***************************************************************************/
  15. /***************************************************************************
  16. Useful include files for winmm component
  17. ***************************************************************************/
  18. #define DEBUG_RETAIL /* Parameter checking is IN */
  19. #if DBG
  20. #ifndef DEBUG
  21. #define DEBUG
  22. #endif
  23. #endif
  24. #ifndef WINMMI_H
  25. #define WINMMI_H /* Protect against double inclusion */
  26. #ifndef RC_INVOKED
  27. #include <string.h>
  28. #include <stdio.h>
  29. #endif /* RC_INVOKED */
  30. #include <windows.h>
  31. #include "mmsystem.h" /* Pick up the public header */
  32. #include "mmsysp.h" /* pick up the internal definitions */
  33. #include "mmcommon.h" /* pick up the definitions common to the NT project */
  34. #ifndef NODDK
  35. #include "mmddkp.h"
  36. #endif
  37. extern BOOL WinmmRunningInWOW; // Are we running in WOW
  38. /*--------------------------------------------------------------------*\
  39. * Unicode helper macros
  40. \*--------------------------------------------------------------------*/
  41. #define SZCODE CHAR
  42. #define WSZCODE WCHAR
  43. #define BYTE_GIVEN_CHAR(x) ( (x) * sizeof( WCHAR ) )
  44. #define CHAR_GIVEN_BYTE(x) ( (x) / sizeof( WCHAR ) )
  45. int Iwcstombs(LPSTR lpstr, LPCWSTR lpwstr, int len);
  46. int Imbstowcs(LPWSTR lpwstr, LPCSTR lpstr, int len);
  47. /***************************************************************************
  48. Definitions to help with common windows code
  49. ***************************************************************************/
  50. #define HPSTR LPSTR
  51. #ifndef RC_INVOKED /* These are defined to RC */
  52. #define STATICDT
  53. #define STATICFN
  54. #define STATIC
  55. #if DBG
  56. extern void InitDebugLevel(void);
  57. void mciCheckLocks(void);
  58. #undef STATICDT
  59. #undef STATICFN
  60. #undef STATIC
  61. #define STATICDT
  62. #define STATICFN
  63. #define STATIC
  64. #else
  65. #define InitDebugLevel()
  66. #endif /* DBG */
  67. #endif /* RC_INVOKED */
  68. /**************************************************************************
  69. **************************************************************************/
  70. #define APPLICATION_DESKTOP_NAME TEXT("Default")
  71. /**************************************************************************
  72. Strings related to INI files
  73. **************************************************************************/
  74. /*
  75. // File and section names for sound aliases
  76. */
  77. #define SOUND_INI_FILE L"win.ini"
  78. #define SOUND_SECTION L"Sounds"
  79. #define SOUND_DEFAULT L".Default"
  80. #define SOUND_RESOURCE_TYPE_SOUND L"SOUND" // in .rc file
  81. #define SOUND_RESOURCE_TYPE_WAVE L"WAVE" // in .rc file
  82. extern WSZCODE szSystemDefaultSound[]; // Name of the default sound
  83. extern WSZCODE szSoundSection[]; // WIN.INI section for sounds
  84. extern WSZCODE wszSystemIni[]; // defined in Winmm.c
  85. extern WSZCODE wszDrivers[]; // defined in Winmm.c
  86. extern WSZCODE wszNull[]; // defined in Winmm.c
  87. // HACK!! HACK!! Should update \nt\private\inc\mmcommon.h
  88. #ifndef MMDRVI_MIXER
  89. #define MMDRVI_MIXER 0x0007
  90. #define MXD_MESSAGE "mxdMessage";
  91. #endif
  92. #define STR_ALIAS_SYSTEMASTERISK 3000
  93. #define STR_ALIAS_SYSTEMQUESTION 3001
  94. #define STR_ALIAS_SYSTEMHAND 3002
  95. #define STR_ALIAS_SYSTEMEXIT 3003
  96. #define STR_ALIAS_SYSTEMSTART 3004
  97. #define STR_ALIAS_SYSTEMWELCOME 3005
  98. #define STR_ALIAS_SYSTEMEXCLAMATION 3006
  99. #define STR_ALIAS_SYSTEMDEFAULT 3007
  100. #define STR_LABEL_APPGPFAULT 3008
  101. #define STR_LABEL_CLOSE 3009
  102. #define STR_LABEL_EMPTYRECYCLEBIN 3010
  103. #define STR_LABEL_MAXIMIZE 3011
  104. #define STR_LABEL_MENUCOMMAND 3012
  105. #define STR_LABEL_MENUPOPUP 3013
  106. #define STR_LABEL_MINIMIZE 3014
  107. #define STR_LABEL_OPEN 3015
  108. #define STR_LABEL_RESTOREDOWN 3016
  109. #define STR_LABEL_RESTOREUP 3017
  110. #define STR_LABEL_RINGIN 3018
  111. #define STR_LABEL_RINGOUT 3019
  112. #define STR_LABEL_SYSTEMASTERISK 3020
  113. #define STR_LABEL_SYSTEMDEFAULT 3021
  114. #define STR_LABEL_SYSTEMEXCLAMATION 3022
  115. #define STR_LABEL_SYSTEMEXIT 3023
  116. #define STR_LABEL_SYSTEMHAND 3024
  117. #define STR_LABEL_SYSTEMQUESTION 3025
  118. #define STR_LABEL_SYSTEMSTART 3026
  119. #define STR_WINDOWS_APP_NAME 3027
  120. #define STR_EXPLORER_APP_NAME 3028
  121. #define STR_JOYSTICKNAME 3029
  122. /*
  123. // File and section names for the mci functions
  124. */
  125. #define MCIDRIVERS_INI_FILE L"system.ini"
  126. #define MCI_HANDLERS MCI_SECTION
  127. /***********************************************************************
  128. *
  129. * Wrap InitializeCriticalSection to make it easier to handle error
  130. *
  131. ***********************************************************************/
  132. _inline BOOL mmInitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
  133. {
  134. try {
  135. InitializeCriticalSection(lpCriticalSection);
  136. return TRUE;
  137. } except (EXCEPTION_EXECUTE_HANDLER) {
  138. return FALSE;
  139. }
  140. }
  141. /***********************************************************************
  142. *
  143. * Speed up profile stuff by going straight to the registry
  144. *
  145. ***********************************************************************/
  146. LONG
  147. RegQuerySzValue(
  148. HKEY hkey,
  149. PCTSTR pValueName,
  150. PTSTR *ppstrValue
  151. );
  152. VOID mmRegFree(VOID);
  153. BOOL
  154. mmRegCreateUserKey (
  155. LPCWSTR lpszPathName,
  156. LPCWSTR lpszKeyName
  157. );
  158. BOOL
  159. mmRegQueryUserKey (
  160. LPCWSTR lpszKeyName
  161. );
  162. BOOL
  163. mmRegDeleteUserKey (
  164. LPCWSTR lpszKeyName
  165. );
  166. BOOL
  167. mmRegSetUserValue (
  168. LPCWSTR lpszSectionName,
  169. LPCWSTR lpszValueName,
  170. LPCWSTR lpszValue
  171. );
  172. BOOL
  173. mmRegQueryUserValue (
  174. LPCWSTR lpszSectionName,
  175. LPCWSTR lpszValueName,
  176. ULONG dwLen,
  177. LPWSTR lpszValue
  178. );
  179. BOOL
  180. mmRegCreateMachineKey (
  181. LPCWSTR lpszPath,
  182. LPCWSTR lpszNewKey
  183. );
  184. BOOL
  185. mmRegSetMachineValue (
  186. LPCWSTR lpszSectionName,
  187. LPCWSTR lpszValueName,
  188. LPCWSTR lpszValue
  189. );
  190. BOOL
  191. mmRegQueryMachineValue (
  192. LPCWSTR lpszSectionName,
  193. LPCWSTR lpszValueName,
  194. ULONG dwLen,
  195. LPWSTR lpszValue
  196. );
  197. DWORD
  198. winmmGetProfileString(
  199. LPCWSTR lpAppName,
  200. LPCWSTR lpKeyName,
  201. LPCWSTR lpDefault,
  202. LPWSTR lpReturnedString,
  203. DWORD nSize
  204. );
  205. DWORD
  206. winmmGetPrivateProfileString(
  207. LPCWSTR lpSection,
  208. LPCWSTR lpKeyName,
  209. LPCWSTR lpDefault,
  210. LPWSTR lpReturnedString,
  211. DWORD nSize,
  212. LPCWSTR lpFileName
  213. );
  214. /***********************************************************************
  215. *
  216. * Used by hwndNotify code
  217. *
  218. ***********************************************************************/
  219. extern BOOL sndMessage( LPWSTR lszSoundName, UINT wFlags );
  220. extern BOOL InitAsyncSound(VOID);
  221. extern CRITICAL_SECTION WavHdrCritSec;
  222. extern CRITICAL_SECTION SoundCritSec;
  223. extern CRITICAL_SECTION mciGlobalCritSec;
  224. /***********************************************************************
  225. *
  226. * Critical section for NumDevs/DeviceID's, and other stuff
  227. *
  228. ***********************************************************************/
  229. extern CRITICAL_SECTION NumDevsCritSec;
  230. extern HANDLE hEventApiInit;
  231. extern CRITICAL_SECTION midiStrmHdrCritSec;
  232. extern CRITICAL_SECTION joyCritSec; //in joy.c, qzheng
  233. extern CRITICAL_SECTION ResolutionCritSec; //in time.c
  234. extern CRITICAL_SECTION TimerThreadCritSec; //in time.c
  235. /***********************************************************************
  236. *
  237. * Flag deduced by initialization to special case running in the server
  238. *
  239. ***********************************************************************/
  240. extern BOOL WinmmRunningInServer; // Are we running in the user/base server?
  241. /***********************************************************************
  242. *
  243. * prototypes from "winmm.c"
  244. *
  245. ***********************************************************************/
  246. void WaveMapperInit(void);
  247. void MidiMapperInit(void);
  248. void midiEmulatorInit(void);
  249. /***********************************************************************
  250. *
  251. * prototypes from "mmiomisc.c"
  252. *
  253. ***********************************************************************/
  254. PBYTE AsciiStrToUnicodeStr( PBYTE pdst, PBYTE pmax, LPCSTR psrc );
  255. PBYTE UnicodeStrToAsciiStr( PBYTE pdst, PBYTE pmax, LPCWSTR psrc);
  256. LPWSTR AllocUnicodeStr( LPCSTR lpSourceStr );
  257. BOOL FreeUnicodeStr( LPWSTR lpStr );
  258. LPSTR AllocAsciiStr( LPCWSTR lpSourceStr );
  259. BOOL FreeAsciiStr( LPSTR lpStr );
  260. /***********************************************************************
  261. *
  262. * prototypes from "mmio.c"
  263. *
  264. ***********************************************************************/
  265. void mmioCleanupIOProcs(HANDLE hTask);
  266. /***********************************************************************
  267. *
  268. * Timer functions
  269. *
  270. ***********************************************************************/
  271. #ifndef MMNOTIMER
  272. BOOL TimeInit(void);
  273. void TimeCleanup(DWORD ThreadId);
  274. UINT timeSetEventInternal(UINT wDelay, UINT wResolution,
  275. LPTIMECALLBACK lpFunction, DWORD_PTR dwUser, UINT wFlags, BOOL IsWOW);
  276. #endif // !MMNOTIMER
  277. /***********************************************************************
  278. *
  279. * Information structure used to play sounds
  280. *
  281. ***********************************************************************/
  282. #define PLAY_NAME_SIZE 256
  283. typedef struct _PLAY_INFO {
  284. HANDLE hModule;
  285. HANDLE hRequestingTask; // Handle of thread that requested sound
  286. DWORD dwFlags;
  287. WCHAR szName[1]; // the structure will be allocated large enough for the name
  288. } PLAY_INFO, *PPLAY_INFO;
  289. #define WAIT_FOREVER ((DWORD)(-1))
  290. /***************************************************************************
  291. global data
  292. ***************************************************************************/
  293. extern HANDLE ghInst;
  294. HANDLE hHeap;
  295. extern DWORD gTlsIndex;
  296. extern BOOL gfDisablePreferredDeviceReordering;
  297. /***************************************************************************
  298. *
  299. * Define the product version to be returned from
  300. * mmsystemgetversion and any other messagebox or
  301. * API that needs the public product version.
  302. *
  303. ***************************************************************************/
  304. #define MMSYSTEM_VERSION 0X030A
  305. typedef UINT MMMESSAGE; // Multi media message type (internal)
  306. #ifndef WM_MM_RESERVED_FIRST // Copy constants from winuserp.h
  307. #define WM_MM_RESERVED_FIRST 0x03A0
  308. #define WM_MM_RESERVED_LAST 0x03DF
  309. #endif
  310. #define MM_POLYMSGBUFRDONE (WM_MM_RESERVED_FIRST+0x2B)
  311. #define MM_SND_PLAY (WM_MM_RESERVED_FIRST+0x2C)
  312. #define MM_SND_ABORT (WM_MM_RESERVED_FIRST+0x2D)
  313. #define MM_SND_SEND (WM_MM_RESERVED_FIRST+0x2E)
  314. #define MM_SND_WAIT (WM_MM_RESERVED_FIRST+0x2F)
  315. #define MCIWAITMSG (MM_SND_WAIT)
  316. #if MM_SND_WAIT > WM_MM_RESERVED_LAST
  317. #error "MM_SND_WAIT is defined beyond the reserved WM_MM range"
  318. #endif
  319. /***************************************************************************
  320. DEBUGGING SUPPORT
  321. ***************************************************************************/
  322. #if DBG
  323. #ifdef DEBUGLEVELVAR
  324. // So that other WINMM related modules can use their own debug level
  325. // variable
  326. #define winmmDebugLevel DEBUGLEVELVAR
  327. #endif
  328. extern int winmmDebugLevel;
  329. extern void winmmDbgOut(LPSTR lpszFormat, ...);
  330. extern void dDbgAssert(LPSTR exp, LPSTR file, int line);
  331. DWORD __dwEval;
  332. extern void winmmDbgOut(LPSTR lpszFormat, ...);
  333. #define dprintf( _x_ ) winmmDbgOut _x_
  334. #define dprintf1( _x_ ) if (winmmDebugLevel >= 1) winmmDbgOut _x_
  335. #define dprintf2( _x_ ) if (winmmDebugLevel >= 2) winmmDbgOut _x_
  336. #define dprintf3( _x_ ) if (winmmDebugLevel >= 3) winmmDbgOut _x_
  337. #define dprintf4( _x_ ) if (winmmDebugLevel >= 4) winmmDbgOut _x_
  338. #define dprintf5( _x_ ) if (winmmDebugLevel >= 5) winmmDbgOut _x_
  339. #define dprintf6( _x_ ) if (winmmDebugLevel >= 6) winmmDbgOut _x_
  340. #define WinAssert(exp) \
  341. ((exp) ? (void)0 : dDbgAssert(#exp, __FILE__, __LINE__))
  342. #define WinEval(exp) \
  343. ((__dwEval=(DWORD)(exp)), \
  344. __dwEval ? (void)0 : dDbgAssert(#exp, __FILE__, __LINE__), __dwEval)
  345. #define DOUT(x) (OutputDebugStringA x, 0)
  346. // #define DOUTX(x) (OutputDebugStringA x, 0)
  347. // #define ROUTS(x) (OutputDebugStringA(x), OutputDebugStringA("\r\n"), 0)
  348. #define ROUTSW(x) (OutputDebugStringW x, OutputDebugStringW(L"\r\n"), 0)
  349. #define ROUT(x) (OutputDebugStringA x, OutputDebugStringA("\r\n"), 0)
  350. // #define ROUTX(x) (OutputDebugStringA(x), 0)
  351. #else
  352. #define dprintf(x) ((void) 0)
  353. #define dprintf1(x) ((void) 0)
  354. #define dprintf2(x) ((void) 0)
  355. #define dprintf3(x) ((void) 0)
  356. #define dprintf4(x) ((void) 0)
  357. #define dprintf5(x) ((void) 0)
  358. #define dprintf6(x) ((void) 0)
  359. #define WinAssert(exp) ((void) 0)
  360. #define WinEval(exp) (exp)
  361. #define DOUT(x) ((void) 0)
  362. // #define DOUTX(x) ((void) 0)
  363. // #define ROUTS(x) ((void) 0)
  364. #define ROUT(x) ((void) 0)
  365. // #define ROUTX(x) ((void) 0)
  366. #endif
  367. /***************************************************************************
  368. Resource IDs
  369. ***************************************************************************/
  370. #define IDS_TASKSTUB 2000
  371. #define STR_MCIUNKNOWN 2001 /* "Unknown error returned from MCI command" */
  372. // #define STR_WAVEINPUT 2004
  373. // #define STR_WAVEOUTPUT 2005
  374. // #define STR_MIDIINPUT 2006
  375. // #define STR_MIDIOUTPUT 2007
  376. #define STR_MCISSERRTXT 2009
  377. #define STR_MCISCERRTXT 2010
  378. #define STR_MIDIMAPPER 2011
  379. #define STR_DRIVERS 2012
  380. #define STR_SYSTEMINI 2013
  381. #define STR_BOOT 2014
  382. /***************************************************************************
  383. Memory allocation using our local heap
  384. ***************************************************************************/
  385. HANDLE hHeap;
  386. PVOID winmmAlloc(DWORD cb);
  387. PVOID winmmReAlloc(PVOID ptr, DWORD cb);
  388. #define winmmFree(ptr) HeapFree(hHeap, 0, (ptr))
  389. void Squirt(LPSTR lpszFormat, ...);
  390. /***************************************************************************
  391. LOCKING AND UNLOCKING MEMORY
  392. ***************************************************************************/
  393. #if 0
  394. BOOL HugePageLock(LPVOID lpArea, DWORD dwLength);
  395. void HugePageUnlock(LPVOID lpArea, DWORD dwLength);
  396. #else
  397. #define HugePageLock(lpArea, dwLength) (TRUE)
  398. #define HugePageUnlock(lpArea, dwLength)
  399. #endif
  400. /***************************************************************************
  401. Pnp Structures and related functions.
  402. ***************************************************************************/
  403. void ClientUpdatePnpInfo();
  404. //#ifdef DBG
  405. #if 0
  406. #define EnterNumDevs(a) Squirt("Allocating NumDevs CS [%s]", a); EnterCriticalSection(&NumDevsCritSec)
  407. #define LeaveNumDevs(a) LeaveCriticalSection(&NumDevsCritSec); Squirt("Releasing NumDevs CS [%s]", a)
  408. #else
  409. #define EnterNumDevs(a) EnterCriticalSection(&NumDevsCritSec)
  410. #define LeaveNumDevs(a) LeaveCriticalSection(&NumDevsCritSec)
  411. #endif
  412. BOOL wdmDevInterfaceInc(IN PCWSTR pstrDeviceInterface);
  413. BOOL wdmDevInterfaceDec(IN PCWSTR pstrDeviceInterface);
  414. /****************************************************************************
  415. API to install/remove/query a MMSYS driver
  416. ****************************************************************************/
  417. /* generic prototype for audio device driver entry-point functions
  418. // midMessage(), modMessage(), widMessage(), wodMessage(), auxMessage()
  419. */
  420. typedef DWORD (APIENTRY *DRIVERMSGPROC)(DWORD, DWORD, DWORD_PTR, DWORD_PTR, DWORD_PTR);
  421. /*
  422. @doc INTERNAL MMSYSTEM
  423. @type UINT | HMD |
  424. This type definition specifies a handle to media resource entry. This
  425. can be used as a unique identifier when specifying a media resource.
  426. */
  427. DECLARE_HANDLE(HMD);
  428. typedef struct _MMDRV* PMMDRV;
  429. void mregAddDriver(IN PMMDRV pdrvZ, IN PMMDRV pdrv);
  430. MMRESULT mregCreateStringIdFromDriverPort(IN PMMDRV pdrv, IN UINT port, OUT PWSTR* pStringId, OUT ULONG* pcbStringId);
  431. MMRESULT mregGetIdFromStringId(IN PMMDRV pdrvZ, IN PCWSTR StringId, OUT UINT *puDeviceID);
  432. BOOL FAR PASCAL mregHandleInternalMessages(IN PMMDRV pdrv, DWORD dwType, UINT Port, UINT msg, DWORD_PTR dw1, DWORD_PTR dw2, MMRESULT * pmmr);
  433. DWORD FAR PASCAL mregDriverInformation(UINT uDeviceID, WORD fwClass, UINT uMessage, DWORD dwParam1, DWORD dwParam2);
  434. UINT FAR PASCAL mregIncUsage(HMD hmd);
  435. UINT FAR PASCAL mregIncUsagePtr(IN PMMDRV pmd);
  436. UINT FAR PASCAL mregDecUsage(HMD hmd);
  437. UINT FAR PASCAL mregDecUsagePtr(IN PMMDRV pmd);
  438. MMRESULT FAR PASCAL mregFindDevice(UINT uDeviceID, WORD fwFindDevice, HMD FAR* phmd, UINT FAR* puDevicePort);
  439. /*****************************************************************************
  440. Driver stuff - This will change when we work out the real
  441. installable driver story on NT
  442. ****************************************************************************/
  443. LRESULT DrvClose(HANDLE hDriver, LPARAM lParam1, LPARAM lParam2);
  444. HANDLE DrvOpen(LPCWSTR szDriverName, LPCWSTR szSectionName, LPARAM lParam2);
  445. LRESULT DrvSendMessage(HANDLE hDriver, UINT message, LPARAM lParam1, LPARAM lParam2);
  446. //HMODULE APIENTRY DrvGetModuleHandle(HDRVR hDriver);
  447. BOOL DrvIsPreXp(IN HANDLE hDriver);
  448. typedef DWORD (DRVPROC)(HANDLE hDriver, UINT msg, LONG lp1, LONG lp2);
  449. typedef DRVPROC *LPDRVPROC;
  450. //
  451. // Init and Cleanup Joystick service, in joy.c
  452. //
  453. BOOL JoyInit(void);
  454. void JoyCleanup(void);
  455. /*
  456. ** Special function for creating threads inside the server process (we only
  457. ** use this to create the thread for playing sounds)
  458. */
  459. BOOLEAN CreateServerPlayingThread(PVOID ThreadStartRoutine);
  460. /*
  461. // exclude some stuff if MMDDK.H is not included
  462. */
  463. #ifdef MMDDKINC /* use this to test for MMDDK.H */
  464. #define MMDRV_DESERTED 0x00000001
  465. #define MMDRV_MAPPER 0x00000002
  466. #define MMDRV_PREXP 0x00000004
  467. //
  468. // base drv instance list node struct
  469. //
  470. typedef struct _MMDRV *PMMDRV;
  471. typedef struct _MMDRV
  472. {
  473. PMMDRV Next;
  474. PMMDRV Prev;
  475. PMMDRV NextStringIdDictNode;
  476. PMMDRV PrevStringIdDictNode;
  477. HANDLE hDriver; /* handle to the module */
  478. WCHAR wszMessage[20]; /* name of entry point */
  479. DRIVERMSGPROC drvMessage; /* pointer to entry point */
  480. ULONG NumDevs; /* number of devices supported */
  481. ULONG Usage; /* usage count (number of handle's open) */
  482. // ISSUE-2001/01/05-FrankYe Rename cookie to DeviceInterface
  483. PCWSTR cookie; /* PnP driver device interface */
  484. DWORD fdwDriver; /* flags for driver */
  485. CRITICAL_SECTION MixerCritSec; /* Serialize use of mixer */
  486. WCHAR wszDrvEntry[64]; /* driver filename */
  487. WCHAR wszSessProtocol[10];
  488. /* Session protocol name, empty
  489. if console driver */
  490. } MMDRV, *PMMDRV;
  491. #ifndef MMNOMIDI
  492. /****************************************************************************
  493. Preferred devices
  494. ****************************************************************************/
  495. void waveOutGetCurrentConsoleVoiceComId(PUINT pPrefId, PDWORD pdwFlags);
  496. void waveOutGetCurrentPreferredId(PUINT pPrefId, PDWORD pdwFlags);
  497. MMRESULT waveOutSetPersistentConsoleVoiceComId(UINT PrefId, DWORD dwFlags);
  498. MMRESULT waveOutSetPersistentPreferredId(UINT PrefId, DWORD dwFlags);
  499. void waveInGetCurrentConsoleVoiceComId(PUINT pPrefId, PDWORD pdwFlags);
  500. void waveInGetCurrentPreferredId(PUINT pPrefId, PDWORD pdwFlags);
  501. MMRESULT waveInSetPersistentPreferredId(UINT PrefId, DWORD dwFlags);
  502. MMRESULT waveInSetPersistentConsoleVoiceComId(UINT PrefId, DWORD dwFlags);
  503. void midiOutGetCurrentPreferredId(PUINT pPrefId, PDWORD dwFlags);
  504. MMRESULT midiOutSetPersistentPreferredId(UINT PrefId, DWORD dwFlags);
  505. void InvalidatePreferredDevices(void);
  506. void RefreshPreferredDevices(void);
  507. /****************************************************************************
  508. Clock routines used by MIDI. These routines provide clocks which run
  509. at the current tempo or SMPTE rate based on timeGetTime().
  510. ****************************************************************************/
  511. typedef DWORD MILLISECS;
  512. typedef long TICKS;
  513. #define CLK_CS_PAUSED 0x00000001L
  514. #define CLK_CS_RUNNING 0x00000002L
  515. #define CLK_TK_NOW ((TICKS)-1L)
  516. //
  517. // This structure is allocated by the client (probably in a handle structure)
  518. // in MMSYSTEM's DS and passed as a near pointer.
  519. //
  520. typedef struct tag_clock *PCLOCK;
  521. typedef DWORD (FAR PASCAL *CLK_TIMEBASE)(PCLOCK);
  522. typedef struct tag_clock
  523. {
  524. MILLISECS msPrev;
  525. TICKS tkPrev;
  526. MILLISECS msT0;
  527. DWORD dwNum;
  528. DWORD dwDenom;
  529. DWORD dwState;
  530. CLK_TIMEBASE fnTimebase;
  531. } CLOCK;
  532. void FAR PASCAL clockInit(PCLOCK pclock, MILLISECS msPrev, TICKS tkPrev, CLK_TIMEBASE fnTimebase);
  533. void FAR PASCAL clockSetRate(PCLOCK pclock, TICKS tkWhen, DWORD dwNum, DWORD dwDenom);
  534. void FAR PASCAL clockPause(PCLOCK pclock, TICKS tkWhen);
  535. void FAR PASCAL clockRestart(PCLOCK pclock, TICKS tkWhen, MILLISECS msWhen);
  536. TICKS FAR PASCAL clockTime(PCLOCK pclock);
  537. MILLISECS FAR PASCAL clockMsTime(PCLOCK pclock);
  538. MILLISECS FAR PASCAL clockOffsetTo(PCLOCK pclock, TICKS tkWhen);
  539. /****************************************************************************
  540. Macros and prototypes shared by the MIDI subsystem.
  541. ****************************************************************************/
  542. // #pragma message() with file/line numbers!
  543. //
  544. #define __PRAGMSG(l,x,c) message(__FILE__"("#l") : "c": "x)
  545. #define _WARN(l,x) __PRAGMSG(l,x, "warning")
  546. #define WARNMSG(x) _WARN(__LINE__,x)
  547. #define _FIX(l,x) __PRAGMSG(l,x, "fix")
  548. #define FIXMSG(x) _FIX(__LINE__,x)
  549. #define DEFAULT_TEMPO 500000L // 500,000 uSec/qn == 120 BPM
  550. #define DEFAULT_TIMEDIV 24 // 24 ticks per quarter note
  551. #define DEFAULT_CBTIMEOUT 100 // 100 milliseconds
  552. #define PM_STATE_READY 0 // polymsg ready to play
  553. #define PM_STATE_BLOCKED 1 // Blocked on outgoing SysEx
  554. #define PM_STATE_EMPTY 2 // No polymsg queued
  555. #define PM_STATE_STOPPED 3 // Just opened/reset/stopped
  556. // No polymsg sent yet.
  557. #define PM_STATE_PAUSED 4 // Paused at some position
  558. #define MIN_PERIOD 1 // millisecs of timer resolution
  559. //
  560. // Macros for dealing with time division dword
  561. //
  562. #define IS_SMPTE 0x00008000L
  563. #define METER_NUM(dw) (UINT)((HIWORD(dw)>>8)&0x00FF)
  564. #define METER_DENOM(dw) (UINT)(HIWORD(dw)&0x00FF)
  565. #define TICKS_PER_QN(dw) (UINT)((dw)&0x7FFF)
  566. #define SMPTE_FORMAT(dw) (((int)((dw)&0xFF00))>>8)
  567. #define TICKS_PER_FRAME(dw) (UINT)((dw)&0x00FF)
  568. //
  569. // Constants for 30-Drop format conversion
  570. //
  571. #define S30D_FRAMES_PER_10MIN 17982
  572. #define S30D_FRAMES_PER_MIN 1798
  573. //
  574. // SMPTE formats from MIDI file time division
  575. //
  576. #define SMPTE_24 24
  577. #define SMPTE_25 25
  578. #define SMPTE_30DROP 29
  579. #define SMPTE_30 30
  580. //
  581. // Stuff that's part of MIDI spec
  582. //
  583. #define MIDI_NOTEOFF (BYTE)(0x80)
  584. #define MIDI_NOTEON (BYTE)(0x90)
  585. #define MIDI_CONTROLCHANGE (BYTE)(0xB0)
  586. #define MIDI_SYSEX (BYTE)(0xF0)
  587. #define MIDI_TIMING_CLK (BYTE)(0xF8)
  588. #define MIDI_SUSTAIN (BYTE)(0x40) // w/ MIDI_CONTROLCHANGE
  589. //
  590. // Indices into dwReserved[] fields of struct
  591. //
  592. // 0,1,2 -- MMSYSTEM (core, emulator)
  593. // 3,4,5 -- MIDI mapper
  594. // 6,7 -- DDK (3rd party drivers)
  595. #define MH_REFCNT 0 // MMSYSTEM core (stream header only)
  596. #define MH_PARENT 0 // MMSYSTEM core (shadow header only)
  597. #define MH_STREAM 0 // Emulator (long msg header only)
  598. #define MH_SHADOW 1 // MMSYSTEM core (stream header only)
  599. #define MH_BUFIDX 1 // Emulator (shadow header only)
  600. #define MH_STRMPME 2 // Emulator (shadow header, long msg header)
  601. /*****************************************************************************
  602. *
  603. * @doc INTERNAL MIDI
  604. *
  605. * @types MIDIDRV | This structure contains all of the information about an
  606. * open <t HMIDIIN> or <t HMIDIOUT> handle.
  607. *
  608. * @field HMD | hmd |
  609. * Handle to media device for this driver.
  610. *
  611. * @field UINT | uDevice |
  612. * Index of this device off of HMD (subunit number relative to this driver).
  613. *
  614. * @field DRIVERMSGPROC | drvMessage |
  615. * Pointer to the associated driver entry point.
  616. *
  617. * @field DWORD | dwDrvUser |
  618. * Driver user DWORD; used by driver to differentiate open instance. Set
  619. * by driver on OPEN message; passed back to driver on every call.
  620. *
  621. * @field PMIDIDRV | pdevNext |
  622. * Specifies the next handle in the linked list of open handles.
  623. * (Only kept for <t HMIDIOUT> handles.
  624. *
  625. * @field UINT | uLockCount |
  626. * Semaphore to serialize access to the handle structure between API calls
  627. * and interrupt callbacks.
  628. *
  629. * @field DWORD | dwTimeDiv |
  630. * The time division setting that is active right now during polymsg playback
  631. * on this handle. The format is the same as described for
  632. * <f midiOutSetTimeDivision>.
  633. *
  634. * @field DWORD | dwTempo |
  635. * Current tempo for polymsg out in microseconds per quarter note (as in the
  636. * Standard MIDI File specification).
  637. *
  638. * @field DWORD | dwPolyMsgState |
  639. * The current state of polymsg playback for emulation.
  640. * @flag PM_STATE_READY | Events may be played and are waiting.
  641. * @flag PM_STATE_BLOCKED | Driver is busy sending SysEx; don't play anything
  642. * else.
  643. * @flag PM_STATE_EMPTY | Not busy but nothing else in the queue to play.
  644. * @flag PM_STATE_PAUSED | Device has been paused with <f midiOutPause>.
  645. *
  646. * @field DWORD | dwSavedState |
  647. * If the device is paused, this field will contain the state to be
  648. * restored when restart occurs.
  649. *
  650. * @field LPMIDIHDR | lpmhFront |
  651. * Front of queue of MIDIHDR's waiting to be played via polymsg in/out. The
  652. * header pointed to by this field is the header currently being played/
  653. * recorded.
  654. *
  655. * @field LPMIDIHDR | lpmhRear |
  656. * End of MIDIHDR queue. Buffers are inserted from the app here.
  657. *
  658. * @field DWORD | dwCallback |
  659. * Address of user callback.
  660. *
  661. * @field DWORD | dwFlags |
  662. * User-supplied callback flags.
  663. *
  664. * @field BOOL | fEmulate |
  665. * TRUE if we are emulating polymsg in/out.
  666. *
  667. * @field BOOL | fReset |
  668. * TRUE if we're in the middle of a MIDM_RESET. Checked to see if we should
  669. * give our shadow buffers back to the driver or retain them for cleanup.
  670. *
  671. * @field BOOL | fStarted |
  672. * TRUE if MIDI input has been started.
  673. *
  674. * @field UINT | uCBTimeout |
  675. * Time in milliseconds that a buffer can be help in MIDI input w/o being
  676. * called back.
  677. *
  678. * @field UINT | uCBTimer |
  679. * Timer ID of the timer which is being used to determine if a MIDI
  680. * input buffer has been queued for too long.
  681. *
  682. * @field DWORD | dwInputBuffers |
  683. * The maximum number of input buffers that have been prepared on this handle.
  684. * Used for calculating shadow buffer pool.
  685. *
  686. * @field DWORD | cbInputBuffers |
  687. * The maximum size of input buffer which has been prepared on this handle.
  688. * Used for calculating shadow buffer pool.
  689. *
  690. * @field DWORD | dwShadowBuffers |
  691. * The current number of shadow buffers allocated on this handle.
  692. *
  693. * @field CLOCK | clock |
  694. * Clock maintained by the clock API's for timebase of both output and
  695. * input emulation.
  696. *
  697. * @field DWORD | tkNextEventDue | Tick time of the next event due
  698. * on polymsg emulation.
  699. *
  700. * @field TICKS | tkTimeOfLastEvent | Tick time that emulator sent the
  701. * last event.
  702. *
  703. * @field DWORD | tkPlayed | Total ticks played on stream.
  704. *
  705. * @field DWORD | tkTime | Tick position in stream now.
  706. *
  707. * @field DWORD | dwTimebase | Flag indicating where timebase is coming
  708. * from. May be one of:
  709. * @flag MIDI_TBF_INTERNAL | Timebase is <f timeGetTime>
  710. * @flag MIDI_TBF_MIDICLK | Timebase is MIDI input clocks.
  711. *
  712. * @field BYTE | rbNoteOn[] | Array of note-on counts per-channel per-note.
  713. * Only allocated for output handles which are doing COOKED mode emulation.
  714. *
  715. *****************************************************************************/
  716. #define ELESIZE(t,e) (sizeof(((t*)NULL)->e))
  717. //#define MDV_F_EXPANDSTATUS 0x00000001L
  718. #define MDV_F_EMULATE 0x00000002L
  719. #define MDV_F_RESET 0x00000004L
  720. #define MDV_F_STARTED 0x00000008L
  721. #define MDV_F_ZOMBIE 0x00000010L
  722. #define MDV_F_SENDING 0x00000020L
  723. #define MDV_F_OWNED 0x00000040L
  724. #define MDV_F_LOCKED 0x00000080L
  725. #define MEM_MAX_LATENESS 64
  726. typedef MMDRV MIDIDRV, *PMIDIDRV;
  727. typedef struct midistrm_tag *PMIDISTRM;
  728. typedef struct mididev_tag *PMIDIDEV;
  729. typedef struct midiemu_tag *PMIDIEMU;
  730. typedef struct mididev_tag {
  731. PMIDIDRV mididrv;
  732. UINT wDevice;
  733. DWORD_PTR dwDrvUser;
  734. UINT uDeviceID;
  735. DWORD fdwHandle;
  736. PMIDIDEV pmThru; /* pointer to midi thru device */
  737. PMIDIEMU pme; /* Iff owned by emulator */
  738. } MIDIDEV;
  739. typedef MIDIDEV *PMIDIDEV;
  740. extern MIDIDRV midioutdrvZ; /* output device driver list */
  741. extern MIDIDRV midiindrvZ; /* input device driver list */
  742. extern UINT wTotalMidiOutDevs; /* total midi output devices */
  743. extern UINT wTotalMidiInDevs; /* total midi input devices */
  744. typedef struct midiemusid_tag {
  745. DWORD dwStreamID;
  746. HMIDI hMidi;
  747. } MIDIEMUSID, *PMIDIEMUSID;
  748. typedef struct midiemu_tag {
  749. PMIDIEMU pNext;
  750. HMIDISTRM hStream;
  751. DWORD fdwDev;
  752. LONG lLockCount; // Must be 32-bit aligned
  753. CRITICAL_SECTION CritSec; // Serialize access
  754. DWORD dwSignature; // Cookie to keep track of validity
  755. DWORD dwTimeDiv; // Time division in use right now
  756. DWORD dwTempo; // Current tempo
  757. DWORD dwPolyMsgState; // Ready or blocked on SysEx
  758. DWORD dwSavedState; // State saved when paused
  759. LPMIDIHDR lpmhFront ; // Front of PolyMsg queue
  760. LPMIDIHDR lpmhRear ; // Rear of PolyMsg queue
  761. DWORD_PTR dwCallback; // User callback
  762. DWORD dwFlags; // User callback flags
  763. DWORD_PTR dwInstance;
  764. DWORD dwSupport; // From MODM_GETDEVCAPS
  765. BYTE bRunningStatus; // Track running status
  766. //
  767. // Rewrite midiOutPolyMsg timekeeping - new stuff!!!
  768. //
  769. CLOCK clock;
  770. TICKS tkNextEventDue; // Tick time of next event
  771. TICKS tkTimeOfLastEvent; // Tick time of last received event
  772. TICKS tkPlayed; // Cumulative ticks played so far
  773. TICKS tkTime; // Tick position in stream *NOW*
  774. LPBYTE rbNoteOn; // Count of notes on per channel per note
  775. UINT cSentLongMsgs; // Oustanding long messages
  776. UINT chMidi; // # Stream ID's
  777. UINT cPostedBuffers; // Posted to mmtask for cleanup
  778. #ifdef DEBUG
  779. DWORD cEvents;
  780. UINT auLateness[MEM_MAX_LATENESS];
  781. // 0..64 milliseconds late
  782. #endif
  783. MIDIEMUSID rIds[]; // HMIDI's indexed by stream ID
  784. } MIDIEMU;
  785. #define MSI_F_EMULATOR 0x00000001L
  786. #define MSI_F_FIRST 0x00000002L
  787. #define MSI_F_OPENED 0x00000004L
  788. #define MSI_F_INITIALIZEDCRITICALSECTION 0x00000008L
  789. #define MSE_SIGNATURE 0x12341234L
  790. typedef struct midistrmid_tag {
  791. HMD hmd;
  792. UINT uDevice;
  793. DRIVERMSGPROC drvMessage;
  794. DWORD_PTR dwDrvUser;
  795. DWORD fdwId;
  796. CRITICAL_SECTION CritSec;
  797. } MIDISTRMID, *PMIDISTRMID;
  798. #define MDS_F_STOPPING 0x00000001L
  799. typedef struct midistrm_tag {
  800. DWORD fdwOpen;
  801. DWORD fdwStrm;
  802. DWORD_PTR dwCallback;
  803. DWORD_PTR dwInstance;
  804. DWORD cDrvrs; // # unique drivers in rgIds[]
  805. DWORD cIds;
  806. MIDISTRMID rgIds[];
  807. } MIDISTRM;
  808. /*****************************************************************************
  809. *
  810. * @doc INTERNAL MIDI
  811. *
  812. * @types MIDIHDREXT |
  813. * This structure is allocated by <f midiOutPolyMsg> and is pointed to by the
  814. * <t reserved> field of the associated <t MIDIHDR>. It contains information
  815. * about what embedded long messages are in the polymsg buffer described
  816. * by the MIDIHDR.
  817. *
  818. * The <t MIDIHDREXT> is followed by multiple <t MIDIDHR> structures, also
  819. * allocated by <f midiOutPolyMsg>, which describe each of the embedded
  820. * long messages which need to be played.
  821. *
  822. * @field DWORD | dwTimeDivision |
  823. * The time division specified with <f midiOutPolyMsg> to play this buffer
  824. * with.
  825. *
  826. * @field UINT | nHeaders |
  827. * The number of <t MIDIHDR> structures which follow the end of this
  828. * <MIDIHDREXT>.
  829. *
  830. * @field LPMIDIHDR | lpmidihdr |
  831. * Pointer to the next <t MIDIHDR> structure due to be played.
  832. *
  833. *
  834. *****************************************************************************/
  835. typedef struct midihdrext_tag {
  836. UINT nHeaders ;
  837. LPMIDIHDR lpmidihdr ;
  838. } MIDIHDREXT, FAR *LPMIDIHDREXT ;
  839. extern HANDLE g_hClosepme;
  840. /*
  841. * Internal prototypes for MIDI
  842. */
  843. extern MMRESULT midiReferenceDriverById(
  844. IN PMIDIDRV pwavedrvZ,
  845. IN UINT id,
  846. OUT PMIDIDRV *ppwavedrv OPTIONAL,
  847. OUT UINT *pport OPTIONAL
  848. );
  849. extern BOOL FAR PASCAL midiLockPageable(void);
  850. extern void NEAR PASCAL midiUnlockPageable(void);
  851. extern MMRESULT NEAR PASCAL midiPrepareHeader(LPMIDIHDR lpMidiHdr, UINT wSize);
  852. extern MMRESULT NEAR PASCAL midiUnprepareHeader(LPMIDIHDR lpMidiHdr, UINT wSize);
  853. extern STATIC MMRESULT midiMessage(HMIDI hMidi, UINT msg, DWORD_PTR dwP1, DWORD_PTR dwP2);
  854. extern DWORD FAR PASCAL midiStreamMessage(PMIDISTRMID pmsi, UINT msg, DWORD_PTR dwP1, DWORD_PTR dwP2);
  855. extern DWORD FAR PASCAL midiStreamBroadcast(PMIDISTRM pms, UINT msg, DWORD_PTR dwP1, DWORD_PTR dwP2);
  856. extern STATIC MMRESULT midiIDMessage(PMIDIDRV pmididrvZ, UINT wTotalNumDevs, UINT_PTR uDeviceID, UINT wMessage, DWORD_PTR dwParam1, DWORD_PTR dwParam2);
  857. extern MMRESULT NEAR PASCAL midiGetPosition(PMIDISTRM pms, LPMMTIME pmmt, UINT cbmmt);
  858. extern MMRESULT NEAR PASCAL midiGetErrorText(MMRESULT wError, LPSTR lpText, UINT wSize);
  859. extern MMRESULT WINAPI midiOutGetID(HMIDIOUT hMidiOut, UINT FAR* lpuDeviceID);
  860. extern MMRESULT FAR PASCAL mseOutSend(PMIDIEMU pme, LPMIDIHDR lpMidiHdr, UINT cbMidiHdr);
  861. extern void FAR PASCAL midiOutSetClockRate(PMIDIEMU pme, TICKS tkWhen);
  862. extern BOOL NEAR PASCAL midiOutScheduleNextEvent(PMIDIEMU pme);
  863. #ifdef DEBUG
  864. extern void NEAR PASCAL midiOutPlayNextPolyEvent(PMIDIEMU pme, DWORD dwStartTime);
  865. #else
  866. extern void NEAR PASCAL midiOutPlayNextPolyEvent(PMIDIEMU pme);
  867. #endif
  868. extern void NEAR PASCAL midiOutDequeueAndCallback(PMIDIEMU pme);
  869. extern void FAR PASCAL midiOutNukePMBuffer(PMIDIEMU pme, LPMIDIHDR lpmh);
  870. extern void CALLBACK midiOutTimerTick(UINT uTimerID, UINT wMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2);
  871. extern void CALLBACK midiOutCallback(HMIDIOUT hMidiOut, WORD wMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2);
  872. extern void NEAR PASCAL midiOutAllNotesOff(PMIDIEMU pme);
  873. extern void CALLBACK midiOutStreamCallback(HMIDISTRM hMidiOut, WORD wMsg, DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2);
  874. extern MMRESULT midiInSetThru (HMIDI hmi, HMIDIOUT hmo, BOOL bAdd);
  875. // mseXXX - MIDI Stream Emulator
  876. //
  877. extern DWORD FAR PASCAL mseMessage(UINT msg, DWORD_PTR dwUser, DWORD_PTR dwParam1, DWORD_PTR dwParam2);
  878. #endif /* ifndef MMNOMIDI */
  879. #ifndef MMNOWAVE
  880. typedef MMDRV WAVEDRV, *PWAVEDRV;
  881. extern WAVEDRV waveoutdrvZ; /* output device driver list */
  882. extern WAVEDRV waveindrvZ; /* input device driver list */
  883. extern UINT wTotalWaveOutDevs; /* total wave output devices */
  884. extern UINT wTotalWaveInDevs; /* total wave input devices */
  885. extern MMRESULT waveReferenceDriverById(
  886. IN PWAVEDRV pwavedrvZ,
  887. IN UINT id,
  888. OUT PWAVEDRV *ppwavedrv OPTIONAL,
  889. OUT UINT *pport OPTIONAL
  890. );
  891. #endif /*ifndef MMNOWAVE */
  892. #ifndef MMNOMIXER
  893. typedef MMDRV MIXERDRV, *PMIXERDRV;
  894. extern MIXERDRV mixerdrvZ; /* mixer device driver list */
  895. extern UINT guTotalMixerDevs; /* total mixer devices */
  896. MMRESULT mixerReferenceDriverById(
  897. IN UINT id,
  898. OUT PMIXERDRV *ppdrv OPTIONAL,
  899. OUT UINT *pport OPTIONAL
  900. );
  901. #endif /*ifndef MMNOMIXER */
  902. #ifndef MMNOAUX
  903. typedef MMDRV AUXDRV, *PAUXDRV;
  904. extern AUXDRV auxdrvZ; /* auxiliary device driver list */
  905. extern UINT wTotalAuxDevs; /* total auxiliary output devices */
  906. MMRESULT auxReferenceDriverById(
  907. IN UINT id,
  908. OUT PAUXDRV *ppauxdrv OPTIONAL,
  909. OUT UINT *pport OPTIONAL
  910. );
  911. #endif /* ifndef MMNOAUX */
  912. #ifdef DEBUG_RETAIL
  913. extern BYTE fIdReverse;
  914. #endif /* ifdef DEBUG_RETAIL */
  915. #endif //ifdef MMDDKINC
  916. /****************************************************************************
  917. handle apis's
  918. ****************************************************************************/
  919. /*
  920. // all MMSYSTEM handles are tagged with the following structure.
  921. //
  922. // a MMSYSTEM handle is really a fixed local memory object.
  923. //
  924. // the functions NewHandle() and FreeHandle() create and release a MMSYSTEM
  925. // handle.
  926. //
  927. */
  928. typedef struct tagHNDL {
  929. struct tagHNDL *pNext; // link to next handle
  930. UINT uType; // type of handle wave, midi, mmio, ...
  931. DWORD fdwHandle; // Particulars about this handle, Deserted? Busy?
  932. HANDLE hThread; // task that owns it
  933. UINT h16; // Corresponding WOW handle
  934. PCWSTR cookie; // Device interface name for driver handles
  935. CRITICAL_SECTION CritSec; // Serialize access
  936. } HNDL, *PHNDL;
  937. /*************************************************************************/
  938. #define MMHANDLE_DESERTED MMDRV_DESERTED
  939. #define MMHANDLE_BUSY 0x00000002
  940. #define HtoPH(h) ((PHNDL)(h)-1)
  941. #define PHtoH(ph) ((ph) ? (HANDLE)((PHNDL)(ph)+1) : 0)
  942. #define HtoPT(t,h) ((t)(h))
  943. #define PTtoH(t,pt) ((t)(pt))
  944. //
  945. // Handles can be tested for ownership and reserved at the same time
  946. //
  947. #define ENTER_MM_HANDLE(h) (EnterCriticalSection(&HtoPH(h)->CritSec))
  948. #define LEAVE_MM_HANDLE(h) ((void)LeaveCriticalSection(&HtoPH(h)->CritSec))
  949. /*
  950. // all wave and midi handles will be linked into
  951. // a global list, so we can enumerate them latter if needed.
  952. //
  953. // all handle structures start with a HNDL structure, that contain common fields
  954. //
  955. // pHandleList points to the first handle in the list
  956. //
  957. // HandleListCritSec protects the handle list
  958. //
  959. // the NewHandle() and FreeHandle() functions are used to add/remove
  960. // a handle to/from the list
  961. */
  962. PHNDL pHandleList;
  963. CRITICAL_SECTION HandleListCritSec;
  964. extern HANDLE NewHandle(UINT uType, PCWSTR cookie, UINT size);
  965. extern void ReleaseHandleListResource();
  966. extern void AcquireHandleListResourceShared();
  967. extern void AcquireHandleListResourceExclusive();
  968. extern void FreeHandle(HANDLE h);
  969. extern void InvalidateHandle(HANDLE h);
  970. #define GetHandleType(h) (HtoPH(h)->uType)
  971. #define GetHandleOwner(h) (HtoPH(h)->hThread)
  972. #define GetHandleFirst() (PHtoH(pHandleList))
  973. #define GetHandleNext(h) (PHtoH(HtoPH(h)->pNext))
  974. #define SetHandleOwner(h,hOwn) (HtoPH(h)->hThread = (hOwn))
  975. #define SetHandleFlag(h,f) (HtoPH(h)->fdwHandle |= (f))
  976. #define ClearHandleFlag(h,f) (HtoPH(h)->fdwHandle &= (~(f)))
  977. #define CheckHandleFlag(h,f) (HtoPH(h)->fdwHandle & (f))
  978. #define IsHandleDeserted(h) (0 != CheckHandleFlag((h), MMHANDLE_DESERTED))
  979. #define IsHandleBusy(h) (0 != CheckHandleFlag((h), MMHANDLE_BUSY))
  980. #define GetWOWHandle(h) (HtoPH(h)->h16)
  981. #define SetWOWHandle(h, myh16) (HtoPH(h)->h16 = (myh16))
  982. /**************************************************************************
  983. Test whether the current process is the WOW process. This
  984. is not a very nice test to have to make but it's the best we
  985. can think of until the WOW people come up with a proper call
  986. **************************************************************************/
  987. #define IS_WOW_PROCESS (NULL != GetModuleHandleW(L"WOW32.DLL"))
  988. /****************************************************************************
  989. user debug support
  990. ****************************************************************************/
  991. #define DebugErr(x,y)
  992. #define DebugErr1(flags, sz, a)
  993. #ifdef DEBUG_RETAIL
  994. #define MM_GET_DEBUG DRV_USER
  995. #define MM_GET_DEBUGOUT DRV_USER+1
  996. #define MM_SET_DEBUGOUT DRV_USER+2
  997. #define MM_GET_MCI_DEBUG DRV_USER+3
  998. #define MM_SET_MCI_DEBUG DRV_USER+4
  999. #define MM_GET_MM_DEBUG DRV_USER+5
  1000. #define MM_SET_MM_DEBUG DRV_USER+6
  1001. #define MM_HINFO_NEXT DRV_USER+10
  1002. #define MM_HINFO_TASK DRV_USER+11
  1003. #define MM_HINFO_TYPE DRV_USER+12
  1004. #define MM_HINFO_MCI DRV_USER+20
  1005. #define MM_DRV_RESTART DRV_USER+30
  1006. /*
  1007. // these validation routines can be found in DEBUG.C
  1008. */
  1009. // The kernel validation is turned OFF because it appeared to test every page
  1010. // before use and this took over a minute for soundrec with a 10MB buffer
  1011. //
  1012. //#define USE_KERNEL_VALIDATION
  1013. #ifdef USE_KERNEL_VALIDATION
  1014. #define ValidateReadPointer(p, len) (!IsBadReadPtr(p, len))
  1015. #define ValidateWritePointer(p, len) (!IsBadWritePtr(p, len))
  1016. #define ValidateString(lsz, max_len) (!IsBadStringPtrA(lsz, max_len))
  1017. #define ValidateStringW(lsz, max_len) (!IsBadStringPtrW(lsz, max_len))
  1018. #else
  1019. BOOL ValidateReadPointer(LPVOID p, DWORD len);
  1020. BOOL ValidateWritePointer(LPVOID p, DWORD len);
  1021. BOOL ValidateString(LPCSTR lsz, DWORD max_len);
  1022. BOOL ValidateStringW(LPCWSTR lsz, DWORD max_len);
  1023. #endif // USE_KERNEL_VALIDATION
  1024. BOOL ValidateHandle(HANDLE h, UINT uType);
  1025. BOOL ValidateHeader(LPVOID p, UINT uSize, UINT uType);
  1026. BOOL ValidateCallbackType(DWORD_PTR dwCallback, UINT uType);
  1027. /********************************************************************
  1028. * When time permits we should change to using the Kernel supplied and
  1029. * supported validation routines:
  1030. *
  1031. * BOOL WINAPI IsBadReadPtr(CONST VOID *lp, UINT ucb );
  1032. * BOOL WINAPI IsBadWritePtr(LPVOID lp, UINT ucb );
  1033. * BOOL WINAPI IsBadHugeReadPtr(CONST VOID *lp, UINT ucb);
  1034. * BOOL WINAPI IsBadHugeWritePtr(LPVOID lp, UINT ucb);
  1035. * BOOL WINAPI IsBadCodePtr(FARPROC lpfn);
  1036. * BOOL WINAPI IsBadStringPtrA(LPCSTR lpsz, UINT ucchMax);
  1037. * BOOL WINAPI IsBadStringPtrW(LPCWSTR lpsz, UINT ucchMax);
  1038. *
  1039. * These routines can be found in * \nt\private\WINDOWS\BASE\CLIENT\PROCESS.C
  1040. *
  1041. ********************************************************************/
  1042. #define V_HANDLE(h, t, r) { if (!ValidateHandle(h, t)) return (r); }
  1043. #define V_HANDLE_ACQ(h, t, r) { AcquireHandleListResourceShared(); if (!ValidateHandle(h, t)) { ReleaseHandleListResource(); return (r);} }
  1044. #define BAD_HANDLE(h, t) ( !(ValidateHandle((h), (t))) )
  1045. #define V_HEADER(p, w, t, r) { if (!ValidateHeader((p), (w), (t))) return (r); }
  1046. #define V_RPOINTER(p, l, r) { if (!ValidateReadPointer((PVOID)(p), (l))) return (r); }
  1047. #define V_RPOINTER0(p, l, r) { if ((p) && !ValidateReadPointer((PVOID)(p), (l))) return (r); }
  1048. #define V_WPOINTER(p, l, r) { if (!ValidateWritePointer((PVOID)(p), (l))) return (r); }
  1049. #define V_WPOINTER0(p, l, r) { if ((p) && !ValidateWritePointer((PVOID)(p), (l))) return (r); }
  1050. #define V_DCALLBACK(d, w, r) { if ((d) && !ValidateCallbackType((d), (w))) return(r); }
  1051. //#define V_DCALLBACK(d, w, r) 0
  1052. #define V_TCALLBACK(d, r) 0
  1053. #define V_CALLBACK(f, r) { if (IsBadCodePtr((f))) return (r); }
  1054. #define V_CALLBACK0(f, r) { if ((f) && IsBadCodePtr((f))) return (r); }
  1055. #define V_STRING(s, l, r) { if (!ValidateString(s,l)) return (r); }
  1056. #define V_STRING_W(s, l, r) { if (!ValidateStringW(s,l)) return (r); }
  1057. #define V_FLAGS(t, b, f, r) { if ((t) & ~(b)) { return (r); }}
  1058. #define V_DFLAGS(t, b, f, r) { if ((t) & ~(b)) {/* LogParamError(ERR_BAD_DFLAGS, (FARPROC)(f), (LPVOID)(DWORD)(t));*/ return (r); }}
  1059. #define V_MMSYSERR(e, f, t, r) { /* LogParamError(e, (FARPROC)(f), (LPVOID)(DWORD)(t));*/ return (r); }
  1060. #else /*ifdef DEBUG_RETAIL */
  1061. #define V_HANDLE(h, t, r) { if (!(h)) return (r); }
  1062. #define V_HANDLE_ACQ(h, t, r) { AcquireHandleListResourceShared(); if (!ValidateHandle(h, t)) { ReleaseHandleListResource(); return (r);} }
  1063. #define BAD_HANDLE(h, t) ( !(ValidateHandle((h), (t))) )
  1064. #define V_HEADER(p, w, t, r) { if (!(p)) return (r); }
  1065. #define V_RPOINTER(p, l, r) { if (!(p)) return (r); }
  1066. #define V_RPOINTER0(p, l, r) 0
  1067. #define V_WPOINTER(p, l, r) { if (!(p)) return (r); }
  1068. #define V_WPOINTER0(p, l, r) 0
  1069. #define V_DCALLBACK(d, w, r) { if ((d) && !ValidateCallbackType((d), (w))) return(r); }
  1070. //#define V_DCALLBACK(d, w, r) 0
  1071. #define V_TCALLBACK(d, r) 0
  1072. #define V_CALLBACK(f, r) { if (IsBadCodePtr((f))) return (r); }
  1073. #define V_CALLBACK0(f, r) { if ((f) && IsBadCodePtr((f))) return (r); }
  1074. //#define V_CALLBACK(f, r) { if (!(f)) return (r); }
  1075. #define V_CALLBACK0(f, r) 0
  1076. #define V_STRING(s, l, r) { if (!(s)) return (r); }
  1077. #define V_STRING_W(s, l, r) { if (!(s)) return (r); }
  1078. #define V_FLAGS(t, b, f, r) 0
  1079. #define V_DFLAGS(t, b, f, r) { if ((t) & ~(b)) return (r); }
  1080. #define V_MMSYSERR(e, f, t, r) { return (r); }
  1081. #endif /* ifdef DEBUG_RETAIL */
  1082. /**************************************************************************
  1083. //
  1084. //**************************************************************************/
  1085. #define TYPE_UNKNOWN 0
  1086. #define TYPE_WAVEOUT 1
  1087. #define TYPE_WAVEIN 2
  1088. #define TYPE_MIDIOUT 3
  1089. #define TYPE_MIDIIN 4
  1090. #define TYPE_MMIO 5
  1091. #define TYPE_MCI 6
  1092. #define TYPE_DRVR 7
  1093. #define TYPE_MIXER 8
  1094. #define TYPE_MIDISTRM 9
  1095. #define TYPE_AUX 10
  1096. /**************************************************************************/
  1097. /****************************************************************************
  1098. RIFF constants used to access wave files
  1099. ****************************************************************************/
  1100. #define FOURCC_FMT mmioFOURCC('f', 'm', 't', ' ')
  1101. #define FOURCC_DATA mmioFOURCC('d', 'a', 't', 'a')
  1102. #define FOURCC_WAVE mmioFOURCC('W', 'A', 'V', 'E')
  1103. extern HWND hwndNotify;
  1104. void FAR PASCAL WaveOutNotify(DWORD wParam, LONG lParam); // in PLAYWAV.C
  1105. /*
  1106. // Things not in Win32
  1107. */
  1108. #define GetCurrentTask() ((HANDLE)(DWORD_PTR)GetCurrentThreadId())
  1109. /*
  1110. // other stuff
  1111. */
  1112. // Maximum length, including the terminating NULL, of an Scheme entry.
  1113. //
  1114. #define SCH_TYPE_MAX_LENGTH 64
  1115. // Maximum length, including the terminating NULL, of an Event entry.
  1116. //
  1117. #define EVT_TYPE_MAX_LENGTH 32
  1118. // Maximum length, including the terminating NULL, of an App entry.
  1119. //
  1120. #define APP_TYPE_MAX_LENGTH 64
  1121. // Sound event names can be a fully qualified filepath with a NULL
  1122. // terminator.
  1123. //
  1124. #define MAX_SOUND_NAME_CHARS 144
  1125. // sound atom names are composed of:
  1126. // <1 char id>
  1127. // <reg key name>
  1128. // <1 char sep>
  1129. // <filepath>
  1130. //
  1131. #define MAX_SOUND_ATOM_CHARS (1 + 40 + 1 + MAX_SOUND_NAME_CHARS)
  1132. #if 0
  1133. #undef hmemcpy
  1134. #define hmemcpy CopyMemory
  1135. #endif
  1136. //
  1137. // for terminal server defination and security
  1138. //
  1139. extern BOOL WinmmRunningInSession;
  1140. extern WCHAR SessionProtocolName[];
  1141. extern BOOL gfLogon;
  1142. BOOL IsWinlogon(void);
  1143. BOOL WTSCurrentSessionIsDisconnected(void);
  1144. // Keep winmm loaded
  1145. extern BOOL LoadWINMM();
  1146. #endif /* WINMMI_H */