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.

751 lines
20 KiB

  1. /****************************************************************************
  2. *
  3. * wdmaud.c
  4. *
  5. * WDM Audio mapper
  6. *
  7. * Copyright (C) Microsoft Corporation, 1997 - 1999 All Rights Reserved.
  8. *
  9. * History
  10. * 5-12-97 - Noel Cross (NoelC)
  11. *
  12. ***************************************************************************/
  13. #include <stdarg.h>
  14. #include "wdmdrv.h"
  15. #include "mixer.h"
  16. #ifdef DEBUG
  17. typedef struct tag_MSGS {
  18. ULONG ulMsg;
  19. char * pString;
  20. } ERROR_MSGS, *PERROR_MSGS;
  21. #define MAPERR(_x_) { _x_, #_x_ }
  22. ERROR_MSGS MsgTable[] = {
  23. //
  24. // Standard error messages
  25. //
  26. MAPERR(MMSYSERR_ERROR),
  27. MAPERR(MMSYSERR_BADDEVICEID),
  28. MAPERR(MMSYSERR_NOTENABLED),
  29. MAPERR(MMSYSERR_ALLOCATED),
  30. MAPERR(MMSYSERR_INVALHANDLE),
  31. MAPERR(MMSYSERR_NODRIVER),
  32. MAPERR(MMSYSERR_NOMEM),
  33. MAPERR(MMSYSERR_NOTSUPPORTED),
  34. MAPERR(MMSYSERR_BADERRNUM),
  35. MAPERR(MMSYSERR_INVALFLAG),
  36. MAPERR(MMSYSERR_INVALPARAM),
  37. MAPERR(MMSYSERR_HANDLEBUSY),
  38. MAPERR(MMSYSERR_INVALIDALIAS),
  39. MAPERR(MMSYSERR_BADDB),
  40. MAPERR(MMSYSERR_KEYNOTFOUND),
  41. MAPERR(MMSYSERR_READERROR),
  42. MAPERR(MMSYSERR_WRITEERROR),
  43. MAPERR(MMSYSERR_DELETEERROR),
  44. MAPERR(MMSYSERR_VALNOTFOUND),
  45. MAPERR(MMSYSERR_NODRIVERCB),
  46. MAPERR(MMSYSERR_MOREDATA),
  47. MAPERR(MMSYSERR_LASTERROR),
  48. //
  49. // Wave error messages
  50. //
  51. MAPERR(WAVERR_BADFORMAT),
  52. MAPERR(WAVERR_STILLPLAYING),
  53. MAPERR(WAVERR_UNPREPARED),
  54. MAPERR(WAVERR_SYNC),
  55. MAPERR(WAVERR_LASTERROR),
  56. //
  57. // Midi Error messages
  58. //
  59. MAPERR(MIDIERR_UNPREPARED),
  60. MAPERR(MIDIERR_STILLPLAYING),
  61. MAPERR(MIDIERR_NOMAP),
  62. MAPERR(MIDIERR_NOTREADY),
  63. MAPERR(MIDIERR_NODEVICE),
  64. MAPERR(MIDIERR_INVALIDSETUP),
  65. MAPERR(MIDIERR_BADOPENMODE),
  66. MAPERR(MIDIERR_DONT_CONTINUE),
  67. MAPERR(MIDIERR_LASTERROR),
  68. //
  69. // Timer errors
  70. //
  71. MAPERR(TIMERR_NOCANDO),
  72. MAPERR(TIMERR_STRUCT),
  73. //
  74. // Joystick error return values
  75. //
  76. MAPERR(JOYERR_PARMS),
  77. MAPERR(JOYERR_NOCANDO),
  78. MAPERR(JOYERR_UNPLUGGED),
  79. //
  80. // MCI Error return codes.
  81. //
  82. MAPERR(MCIERR_INVALID_DEVICE_ID),
  83. MAPERR(MCIERR_UNRECOGNIZED_KEYWORD),
  84. MAPERR(MCIERR_UNRECOGNIZED_COMMAND),
  85. MAPERR(MCIERR_HARDWARE),
  86. MAPERR(MCIERR_INVALID_DEVICE_NAME),
  87. MAPERR(MCIERR_OUT_OF_MEMORY),
  88. MAPERR(MCIERR_DEVICE_OPEN),
  89. MAPERR(MCIERR_CANNOT_LOAD_DRIVER),
  90. MAPERR(MCIERR_MISSING_COMMAND_STRING),
  91. MAPERR(MCIERR_BAD_INTEGER),
  92. MAPERR(MCIERR_PARSER_INTERNAL),
  93. MAPERR(MCIERR_DRIVER_INTERNAL),
  94. MAPERR(MCIERR_MISSING_PARAMETER),
  95. MAPERR(MCIERR_UNSUPPORTED_FUNCTION),
  96. MAPERR(MCIERR_FILE_NOT_FOUND),
  97. MAPERR(MCIERR_DEVICE_NOT_READY),
  98. MAPERR(MCIERR_INTERNAL),
  99. MAPERR(MCIERR_DRIVER),
  100. MAPERR(MCIERR_CANNOT_USE_ALL),
  101. MAPERR(MCIERR_MULTIPLE),
  102. MAPERR(MCIERR_EXTENSION_NOT_FOUND),
  103. MAPERR(MCIERR_OUTOFRANGE),
  104. MAPERR(MCIERR_FLAGS_NOT_COMPATIBLE), //sphelling?
  105. MAPERR(MCIERR_FILE_NOT_SAVED),
  106. MAPERR(MCIERR_DEVICE_TYPE_REQUIRED),
  107. MAPERR(MCIERR_DEVICE_LOCKED),
  108. MAPERR(MCIERR_DUPLICATE_ALIAS),
  109. MAPERR(MCIERR_BAD_CONSTANT),
  110. MAPERR(MCIERR_MUST_USE_SHAREABLE),
  111. MAPERR(MCIERR_MISSING_DEVICE_NAME),
  112. MAPERR(MCIERR_BAD_TIME_FORMAT),
  113. MAPERR(MCIERR_NO_CLOSING_QUOTE),
  114. MAPERR(MCIERR_DUPLICATE_FLAGS),
  115. MAPERR(MCIERR_INVALID_FILE),
  116. MAPERR(MCIERR_NULL_PARAMETER_BLOCK),
  117. MAPERR(MCIERR_UNNAMED_RESOURCE),
  118. MAPERR(MCIERR_NEW_REQUIRES_ALIAS),
  119. MAPERR(MCIERR_NOTIFY_ON_AUTO_OPEN),
  120. MAPERR(MCIERR_NO_ELEMENT_ALLOWED),
  121. MAPERR(MCIERR_NONAPPLICABLE_FUNCTION),
  122. MAPERR(MCIERR_ILLEGAL_FOR_AUTO_OPEN),
  123. MAPERR(MCIERR_FILENAME_REQUIRED),
  124. MAPERR(MCIERR_EXTRA_CHARACTERS),
  125. MAPERR(MCIERR_DEVICE_NOT_INSTALLED),
  126. MAPERR(MCIERR_GET_CD),
  127. MAPERR(MCIERR_SET_CD),
  128. MAPERR(MCIERR_SET_DRIVE),
  129. MAPERR(MCIERR_DEVICE_LENGTH),
  130. MAPERR(MCIERR_DEVICE_ORD_LENGTH),
  131. MAPERR(MCIERR_NO_INTEGER),
  132. MAPERR(MCIERR_WAVE_OUTPUTSINUSE),
  133. MAPERR(MCIERR_WAVE_SETOUTPUTINUSE),
  134. MAPERR(MCIERR_WAVE_INPUTSINUSE),
  135. MAPERR(MCIERR_WAVE_SETINPUTINUSE),
  136. MAPERR(MCIERR_WAVE_OUTPUTUNSPECIFIED),
  137. MAPERR(MCIERR_WAVE_INPUTUNSPECIFIED),
  138. MAPERR(MCIERR_WAVE_OUTPUTSUNSUITABLE),
  139. MAPERR(MCIERR_WAVE_SETOUTPUTUNSUITABLE),
  140. MAPERR(MCIERR_WAVE_INPUTSUNSUITABLE),
  141. MAPERR(MCIERR_WAVE_SETINPUTUNSUITABLE),
  142. MAPERR(MCIERR_SEQ_DIV_INCOMPATIBLE),
  143. MAPERR(MCIERR_SEQ_PORT_INUSE),
  144. MAPERR(MCIERR_SEQ_PORT_NONEXISTENT),
  145. MAPERR(MCIERR_SEQ_PORT_MAPNODEVICE),
  146. MAPERR(MCIERR_SEQ_PORT_MISCERROR),
  147. MAPERR(MCIERR_SEQ_TIMER),
  148. MAPERR(MCIERR_SEQ_PORTUNSPECIFIED),
  149. MAPERR(MCIERR_SEQ_NOMIDIPRESENT),
  150. MAPERR(MCIERR_NO_WINDOW),
  151. MAPERR(MCIERR_CREATEWINDOW),
  152. MAPERR(MCIERR_FILE_READ),
  153. MAPERR(MCIERR_FILE_WRITE),
  154. MAPERR(MCIERR_NO_IDENTITY),
  155. //
  156. // Mixer return values
  157. //
  158. MAPERR(MIXERR_INVALLINE),
  159. MAPERR(MIXERR_INVALCONTROL),
  160. MAPERR(MIXERR_INVALVALUE),
  161. MAPERR(MIXERR_LASTERROR),
  162. {0xDEADBEEF,"DEADBEEF"},
  163. //
  164. // Don't walk off the end of the list
  165. //
  166. {0,NULL},
  167. {0,"Unknown"}
  168. };
  169. //-----------------------------------------------------------------------------
  170. // Globals that affect debug output:
  171. //-----------------------------------------------------------------------------
  172. //
  173. // The documentation relies on these two variables being next to each other
  174. // with uiDebugLevel first. Do not separate them.
  175. //
  176. // Default to displaying all "Warning" messages
  177. UINT uiDebugLevel = DL_WARNING ;
  178. // Default to breaking on all "Error" messages
  179. UINT uiDebugBreakLevel = DL_ERROR ;
  180. char szReturningErrorStr[]="Ret Err %X:%s";
  181. // for storing the deviceinfo's in debug.
  182. //PDINODE gpdiActive=NULL;
  183. //PDINODE gpdiFreeHead=NULL;
  184. //PDINODE gpdiFreeTail=NULL;
  185. //INT giFree=0;
  186. //INT giAlloc=0;
  187. //INT giFreed=0;
  188. //
  189. // Make header for these functions....
  190. //
  191. char *MsgToAscii(ULONG ulMsg)
  192. {
  193. PERROR_MSGS pTable=MsgTable;
  194. while(pTable->pString != NULL)
  195. {
  196. if (pTable->ulMsg==ulMsg) return pTable->pString;
  197. pTable++;
  198. }
  199. pTable++;
  200. //
  201. // If we get to the end of the list advance the pointer and return
  202. // "Unknown"
  203. //
  204. return pTable->pString;
  205. }
  206. VOID wdmaudDbgBreakPoint()
  207. {
  208. DbgBreak();
  209. }
  210. //
  211. // This routine will format the start of the string. But, before it does that
  212. // it will check to see if the user should even be seeing this message.
  213. //
  214. // uiMsgLevel is the flags in the code that classify the message. This value
  215. // is used if and only if the user is filtering on that class of messages.
  216. //
  217. // If the message is to be displayed, the return value will be non-zero so that
  218. // the message in the code will be displayed. See the macro DPF.
  219. //
  220. UINT wdmaudDbgPreCheckLevel(UINT uiMsgLevel,char *pFunction,int iLine)
  221. {
  222. char szBuf[24];
  223. UINT uiRet=0;
  224. //
  225. // Read this like: if there is a bit set in the upper 3 bytes of the uiDebugLevel
  226. // variable, then the user is viewing messages of a specific type. We only
  227. // want to show those messages.
  228. //
  229. if( (uiDebugLevel&FA_MASK) )
  230. {
  231. //
  232. // Yes, the user filtering on a particular class of messages. Did
  233. // we find one to display? We look at the message flags to determine this.
  234. //
  235. if( (uiMsgLevel&FA_MASK) & (uiDebugLevel&FA_MASK) )
  236. {
  237. //
  238. // Yes, we found a message of the right class. Is it at the right
  239. // level for the user to see?
  240. //
  241. if( (uiMsgLevel&DL_MASK) <= (uiDebugLevel&DL_MASK) ) {
  242. // Yes.
  243. uiRet=1;
  244. }
  245. }
  246. } else {
  247. // The user is not viewing a specific type of message "class". Do we have
  248. // a message level worth displaying?
  249. if( (uiMsgLevel&DL_MASK) <= (uiDebugLevel&DL_MASK) )
  250. {
  251. // Yes.
  252. uiRet=1;
  253. }
  254. }
  255. // Now just check to see if we need to display on this call.
  256. if( uiRet )
  257. {
  258. // Yes. Every message needs to start where it's from!
  259. OutputDebugStringA("WDMAUD.DRV ");
  260. OutputDebugStringA(pFunction);
  261. wsprintfA(szBuf,"(%d)",iLine);
  262. OutputDebugStringA(szBuf);
  263. // Now lable it's type.
  264. switch(uiMsgLevel&DL_MASK)
  265. {
  266. case DL_ERROR:
  267. OutputDebugStringA(" Error ");
  268. break;
  269. case DL_WARNING:
  270. OutputDebugStringA(" Warning ");
  271. break;
  272. case DL_TRACE:
  273. OutputDebugStringA(" Trace ");
  274. break;
  275. case DL_MAX:
  276. OutputDebugStringA(" Max ");
  277. break;
  278. default:
  279. break;
  280. }
  281. // when uiRet is positive, we've displayed the header info. Tell the
  282. // macro that we're in display mode.
  283. }
  284. return uiRet;
  285. }
  286. UINT wdmaudDbgPostCheckLevel(UINT uiMsgLevel)
  287. {
  288. UINT uiRet=0;
  289. // char szBuf[32];
  290. // Always finish the line.
  291. // wsprintfA(szBuf," &DL=%08X",&uiDebugLevel);
  292. // OutputDebugStringA(szBuf);
  293. #ifdef HTTP
  294. OutputDebugStringA(", see \\\\debugtips\\msgs\\wdmauds.htm\n");
  295. #else
  296. OutputDebugStringA("\n");
  297. #endif
  298. //
  299. // Ok, here is the scoop. uiDebugBreakLevel is set to DL_ERROR (0) by default
  300. // thus, any time we get an error message of DL_ERROR level we will break.
  301. //
  302. // Also, uiDebugBreakLevel can be set by the user to DL_WARNING or DL_TRACE
  303. // or DL_MAX. If so, any time we encounter a message with this debug level
  304. // we will break in the debugger.
  305. //
  306. //
  307. if( (uiMsgLevel&DL_MASK) <= uiDebugBreakLevel )
  308. {
  309. // The user wants to break on these messages.
  310. DbgBreak();
  311. uiRet = 1;
  312. }
  313. return uiRet;
  314. }
  315. VOID FAR __cdecl wdmaudDbgOut
  316. (
  317. LPSTR lpszFormat,
  318. ...
  319. )
  320. {
  321. char buf[256];
  322. va_list va;
  323. va_start(va, lpszFormat);
  324. wvsprintfA(buf, lpszFormat, va);
  325. va_end(va);
  326. OutputDebugStringA(buf);
  327. }
  328. #endif // DEBUG
  329. MMRESULT
  330. IsValidMidiDataListEntry(
  331. LPMIDIDATALISTENTRY pMidiDataListEntry
  332. )
  333. {
  334. MMRESULT mmr;
  335. if ( IsBadWritePtr( (LPVOID)(pMidiDataListEntry),sizeof(MIDIDATALISTENTRY) ) )
  336. {
  337. DPF(DL_ERROR|FA_ALL, ("Corrupted MidiDataListEntry %X",pMidiDataListEntry) );
  338. return MMSYSERR_INVALPARAM;
  339. }
  340. #ifdef DEBUG
  341. if( pMidiDataListEntry->dwSig != MIDIDATALISTENTRY_SIGNATURE )
  342. {
  343. DPF(DL_ERROR|FA_ALL, ("Invalid MidiDataListEntry Signature %X",pMidiDataListEntry) );
  344. return MMSYSERR_INVALPARAM;
  345. }
  346. #endif
  347. if( (mmr=IsValidOverLapped(pMidiDataListEntry->pOverlapped)) != MMSYSERR_NOERROR )
  348. {
  349. return mmr;
  350. }
  351. return MMSYSERR_NOERROR;
  352. }
  353. ////////////////////////////////////////////////////////////////////////////////
  354. //
  355. // IsValidPrepareWaveHeader
  356. //
  357. // This routine is available in debug or retail to validate that we've got a valid
  358. // structure. In retail, we ask the OS if we've got a valid memory pointer. In
  359. // debug we also check other fields
  360. //
  361. // See WAVEPREPAREDATA structure
  362. //
  363. // returns MMSYSERR_NOERROR on success, error code otherwise.
  364. //
  365. MMRESULT
  366. IsValidPrepareWaveHeader(
  367. PWAVEPREPAREDATA pPrepare
  368. )
  369. {
  370. MMRESULT mmr;
  371. if ( IsBadWritePtr( (LPVOID)(pPrepare),sizeof(PWAVEPREPAREDATA) ) )
  372. {
  373. DPF(DL_ERROR|FA_ALL, ("Corrupted PrepareData %X",pPrepare) );
  374. return MMSYSERR_INVALPARAM;
  375. }
  376. #ifdef DEBUG
  377. if ( pPrepare->dwSig != WAVEPREPAREDATA_SIGNATURE )
  378. {
  379. DPF(DL_ERROR|FA_ALL, ("Invalid PrepareData signature!") );
  380. return MMSYSERR_INVALPARAM;
  381. }
  382. #endif
  383. if( (mmr=IsValidOverLapped(pPrepare->pOverlapped)) != MMSYSERR_NOERROR )
  384. {
  385. return mmr;
  386. }
  387. return MMSYSERR_NOERROR;
  388. }
  389. ////////////////////////////////////////////////////////////////////////////////
  390. //
  391. // IsValidOverlapped
  392. //
  393. // Validates the overlapped structure.
  394. //
  395. // returns MMSYSERR_NOERROR on success, error code on failure.
  396. //
  397. MMRESULT
  398. IsValidOverLapped(
  399. LPOVERLAPPED lpol
  400. )
  401. {
  402. if ( IsBadWritePtr( (LPVOID)(lpol),sizeof(OVERLAPPED) ) )
  403. {
  404. DPF(DL_ERROR|FA_ALL, ("Invalid Overlapped structure %X",lpol) );
  405. return MMSYSERR_INVALPARAM;
  406. }
  407. if( lpol->hEvent == NULL )
  408. {
  409. DPF(DL_ERROR|FA_ASSERT,("Invalid hEvent Overlapped=%08X",lpol) );
  410. return MMSYSERR_INVALPARAM;
  411. }
  412. return MMSYSERR_NOERROR;
  413. }
  414. ////////////////////////////////////////////////////////////////////////////////
  415. //
  416. // IsValidDeviceState
  417. //
  418. // This routine is used in both debug and retail. In retail it validates that
  419. // the pointer that is passed in is the correct size and type. Under debug
  420. // it checks other fields.
  421. //
  422. // See DEVICESTATE structure
  423. //
  424. // returns MMSYSERR_NOERROR on success, error code otherwise.
  425. //
  426. MMRESULT
  427. IsValidDeviceState(
  428. LPDEVICESTATE lpDeviceState,
  429. BOOL bFullyConfigured
  430. )
  431. {
  432. if ( IsBadWritePtr( (LPVOID)(lpDeviceState),sizeof(DEVICESTATE) ) )
  433. {
  434. DPF(DL_ERROR|FA_ALL, ("Invalid DeviceState %X",lpDeviceState) );
  435. return MMSYSERR_INVALPARAM;
  436. }
  437. if( lpDeviceState->csQueue == NULL )
  438. {
  439. DPF(DL_ERROR|FA_ASSERT,("Invalid csQueue in DeviceState %08X",lpDeviceState) );
  440. return MMSYSERR_INVALPARAM;
  441. }
  442. #ifdef DEBUG
  443. if( lpDeviceState->dwSig != DEVICESTATE_SIGNATURE )
  444. {
  445. DPF(DL_ERROR|FA_ALL, ("Invalid DeviceState dwSig %08X",lpDeviceState) );
  446. return MMSYSERR_INVALPARAM;
  447. }
  448. if( bFullyConfigured )
  449. {
  450. //
  451. // Now, check to see that the items in the structure looks good.
  452. //
  453. if( ( lpDeviceState->hevtExitThread == NULL ) ||
  454. ( lpDeviceState->hevtExitThread == (HANDLE)FOURTYEIGHT ) )
  455. {
  456. DPF(DL_ERROR|FA_ASSERT,("Invalid hevtExitThread in DeviceState %08X",lpDeviceState) );
  457. return MMSYSERR_INVALPARAM;
  458. }
  459. if( (lpDeviceState->hevtQueue == NULL) ||
  460. (lpDeviceState->hevtQueue == (HANDLE)FOURTYTWO) ||
  461. (lpDeviceState->hevtQueue == (HANDLE)FOURTYTHREE) )
  462. {
  463. DPF(DL_ERROR|FA_ASSERT,("Invalid hevtQueue in DeviceState %08X",lpDeviceState) );
  464. return MMSYSERR_INVALPARAM;
  465. }
  466. }
  467. #endif
  468. return MMSYSERR_NOERROR;
  469. }
  470. ////////////////////////////////////////////////////////////////////////////////
  471. //
  472. // IsValidDeviceInfo
  473. //
  474. // In retail, we validate that we have a pointer of the correct size and type.
  475. // In debug we walk our active deviceinfo list and see if we can find it. If
  476. // we can't, we'll look in our freed list to see if it's there. Basically, when
  477. // someone frees a deviceinfo structure, we add it to the freed list. After the
  478. // freed list grows to 100 in length, we start rolling them off the list and freeing
  479. // them. On shutdown, we clean them all up.
  480. //
  481. // See DEVICEINFO Structure
  482. //
  483. // returns MMSYSERR_NOERROR on success, error code otherwise.
  484. //
  485. MMRESULT
  486. IsValidDeviceInfo(
  487. LPDEVICEINFO lpDeviceInfo
  488. )
  489. {
  490. LPDEVICEINFO lpdi;
  491. if ( IsBadWritePtr( (LPVOID)(lpDeviceInfo),sizeof(DEVICEINFO) ) )
  492. {
  493. DPF(DL_ERROR|FA_ALL, ("Invalid DeviceInfo %X",lpDeviceInfo) );
  494. return MMSYSERR_INVALPARAM;
  495. }
  496. #ifdef DEBUG
  497. if( lpDeviceInfo->dwSig != DEVICEINFO_SIGNATURE )
  498. {
  499. DPF(DL_ERROR|FA_ALL,("Invalid DeviceInfo %08x Signature!",lpDeviceInfo) );
  500. return MMSYSERR_INVALPARAM;
  501. }
  502. #endif
  503. return MMSYSERR_NOERROR;
  504. }
  505. ////////////////////////////////////////////////////////////////////////////////
  506. //
  507. // IsValidWaveHeader
  508. //
  509. // In retail we validate that this pointer is of the correct size and type. In
  510. // debug we validate some flags and look for signatures.
  511. //
  512. // See WAVEHDR structure
  513. //
  514. // returns MMRERR_NOERROR on success, Error code otherwise.
  515. //
  516. // Note:
  517. //
  518. // To do this, the LPWAVEHDR structure is defined in mmsystem.h, thus we can not
  519. // add a signiture to that structure. But, we do add info to the reserved field
  520. // that is a WAVEPREPAREDATA structure. That structure has a signiture. Thus,
  521. // we'll add that check to this routine.
  522. //
  523. // To pass, the wave header must be a write pointer of the correct size. The dwFLags
  524. // field must not have any extra flags in it and the reserved field must be a
  525. // WAVEPREPAREDATA pointer.
  526. //
  527. MMRESULT
  528. IsValidWaveHeader(
  529. LPWAVEHDR pWaveHdr
  530. )
  531. {
  532. PWAVEPREPAREDATA pwavePrepareData;
  533. if ( IsBadWritePtr( (LPVOID)(pWaveHdr),sizeof(WAVEHDR) ) )
  534. {
  535. DPF(DL_ERROR|FA_ALL, ("Invalid pWaveHdr pointer %X",pWaveHdr) );
  536. return MMSYSERR_INVALPARAM;
  537. }
  538. #ifdef DEBUG
  539. if( pWaveHdr->dwFlags & ~(WHDR_DONE|WHDR_PREPARED|WHDR_BEGINLOOP|WHDR_ENDLOOP|WHDR_INQUEUE) )
  540. {
  541. DPF(DL_ERROR|FA_ALL,("Ivalid dwFlags %08x in pWaveHdr %08X",
  542. pWaveHdr->dwFlags,pWaveHdr) );
  543. return MMSYSERR_INVALPARAM;
  544. }
  545. #endif
  546. /*
  547. if (!(pWaveHdr->dwFlags & WHDR_PREPARED))
  548. {
  549. DPF(DL_ERROR|FA_ASSERT,("Unprepared header %08X",pWaveHdr) );
  550. return( WAVERR_UNPREPARED );
  551. }
  552. */
  553. if ((DWORD_PTR)pWaveHdr->reserved == (DWORD_PTR)NULL)
  554. {
  555. return( WAVERR_UNPREPARED );
  556. } else {
  557. if ( IsBadWritePtr( (LPVOID)(pWaveHdr->reserved),sizeof(WAVEPREPAREDATA) ) )
  558. {
  559. DPF(DL_ERROR|FA_ALL, ("Invalid pWaveHdr->reserved %X",pWaveHdr->reserved) );
  560. return MMSYSERR_INVALPARAM;
  561. }
  562. }
  563. #ifdef DEBUG
  564. pwavePrepareData = (PWAVEPREPAREDATA)pWaveHdr->reserved;
  565. if( pwavePrepareData->dwSig != WAVEPREPAREDATA_SIGNATURE )
  566. {
  567. DPF(DL_ERROR|FA_ALL,("Invalid Signature in WAVEPREPAREDATA structure!") );
  568. return MMSYSERR_INVALPARAM;
  569. }
  570. #endif
  571. return MMSYSERR_NOERROR;
  572. }
  573. MMRESULT
  574. IsValidMidiHeader(
  575. LPMIDIHDR pMidiHdr
  576. )
  577. {
  578. if ( IsBadWritePtr( (LPVOID)(pMidiHdr),sizeof(MIDIHDR) ) )
  579. {
  580. DPF(DL_ERROR|FA_ALL, ("Invalid pMidiHdr %X",pMidiHdr) );
  581. return MMSYSERR_INVALPARAM;
  582. }
  583. return MMSYSERR_NOERROR;
  584. }
  585. MMRESULT
  586. IsValidWaveOpenDesc(
  587. LPWAVEOPENDESC pwod
  588. )
  589. {
  590. if ( IsBadWritePtr( (LPVOID)(pwod),sizeof(WAVEOPENDESC) ) )
  591. {
  592. DPF(DL_ERROR|FA_ALL, ("Invalid pwod %X",pwod) );
  593. return MMSYSERR_INVALPARAM;
  594. }
  595. return MMSYSERR_NOERROR;
  596. }
  597. ////////////////////////////////////////////////////////////////////////////////
  598. //
  599. // IsValidMixerInstance
  600. //
  601. // Validates that the pointer is the correct type and size. Debug checks for
  602. // the correct signature.
  603. //
  604. // returns TRUE on success FALSE otherwise.
  605. //
  606. MMRESULT
  607. IsValidMixerInstance(
  608. LPMIXERINSTANCE lpmi
  609. )
  610. {
  611. LPMIXERINSTANCE currentinstance;
  612. if ( IsBadWritePtr( (LPVOID)(lpmi),sizeof(MIXERINSTANCE) ) )
  613. {
  614. DPF(DL_ERROR|FA_ALL, ("Invalid MixerInstance structure %X",lpmi) );
  615. return MMSYSERR_INVALPARAM;
  616. }
  617. #ifdef DEBUG
  618. if( lpmi->dwSig != MIXERINSTANCE_SIGNATURE )
  619. {
  620. DPF(DL_ERROR|FA_ALL,("Invalid Signature in MixerInstance %08X",lpmi) );
  621. return MMSYSERR_INVALPARAM;
  622. }
  623. #endif
  624. for (currentinstance=pMixerDeviceList;currentinstance!=NULL;currentinstance=currentinstance->Next)
  625. if (currentinstance==lpmi)
  626. return MMSYSERR_NOERROR;
  627. DPF(DL_ERROR|FA_ALL, ("Invalid Instance passed to mxdMessage in dwUser!") );
  628. // Since tracking down the WINMM bug that causes this assert to fire is
  629. // proving very difficult and fwong (current winmm owner) is blowing it off
  630. // and I (joeball) have more important things to do, I am turning off this assert.
  631. // We still spew, but simply fail the api calls that don't have what we think
  632. // is valid instance data.
  633. // I currently think it is one of 2 things: either the winmm usage count is wrapping -
  634. // higher than 255 - a possibility because of the PNP recursive calls
  635. // in winmm, OR, the CleanUpDesertedHandles in the UpdateClientPnpInfo is
  636. // getting stuff closed just before it is used. Either is a very likely
  637. // possibility.
  638. //DPFASSERT( 0 );
  639. return MMSYSERR_INVALPARAM;
  640. }
  641. ////////////////////////////////////////////////////////////////////////////////
  642. //
  643. // IsValidDeviceInterface
  644. //
  645. // This routine simply validates that we have a pointer to at least 1 byte that
  646. // is readable. In debug we check to make sure that the string is not absurd.
  647. //
  648. // returns TRUE on success FALSE otherwise.
  649. //
  650. BOOL
  651. IsValidDeviceInterface(
  652. LPCWSTR DeviceInterface
  653. )
  654. {
  655. if ( IsBadReadPtr( (LPVOID)(DeviceInterface),1 ) )
  656. {
  657. DPF(DL_ERROR|FA_ALL, ("Invalid DeviceInterface string %08X",DeviceInterface) );
  658. return FALSE;
  659. }
  660. #ifdef DEBUG
  661. if( (sizeof(WCHAR)*lstrlenW(DeviceInterface)) > 4096 )
  662. {
  663. DPF(DL_ERROR|FA_ALL, ("Invalid DeviceInterface string %08X",DeviceInterface) );
  664. return FALSE;
  665. }
  666. #endif
  667. return TRUE;
  668. }