Leaked source code of windows server 2003
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.

456 lines
11 KiB

  1. //==========================================================================;
  2. //
  3. // wavein.c
  4. //
  5. // Copyright (c) 1992-1998 Microsoft Corporation
  6. //
  7. // Description:
  8. //
  9. //
  10. // History:
  11. // 9/18/93 cjp [curtisp]
  12. //
  13. //==========================================================================;
  14. #include <windows.h>
  15. #include <windowsx.h>
  16. #include <mmsystem.h>
  17. #include <mmddk.h>
  18. #include <mmreg.h>
  19. #include <msacm.h>
  20. #include <msacmdrv.h>
  21. #include <memory.h>
  22. #ifdef DEBUG
  23. #include <stdlib.h>
  24. #endif
  25. #include "msacmmap.h"
  26. #include "debug.h"
  27. //--------------------------------------------------------------------------;
  28. //
  29. // LRESULT mapWaveInputConvertProc
  30. //
  31. // Description:
  32. // Window Proc for hidden window...
  33. //
  34. // It should just recieve WIM_DATA messages from mapWaveDriverCallback
  35. //
  36. // Real driver has filled the shadow buffer
  37. // Now convert it and call back the app/client.
  38. //
  39. // Arguments:
  40. // DWORD dwInstance:
  41. //
  42. // Return (LONG):
  43. //
  44. // History:
  45. // 11/15/92 gpd [geoffd]
  46. // 08/02/93 cjp [curtisp] rewrote for new mapper
  47. //
  48. //--------------------------------------------------------------------------;
  49. EXTERN_C LRESULT FNCALLBACK mapWaveInputConvertProc
  50. (
  51. DWORD dwInstance
  52. )
  53. {
  54. MMRESULT mmr;
  55. MSG msg;
  56. LPACMSTREAMHEADER pash;
  57. LPWAVEHDR pwh;
  58. LPWAVEHDR pwhShadow;
  59. LPMAPSTREAM pms;
  60. #ifndef WIN32
  61. DPF(1, "mapWaveInputConvertProc: creating htask=%.04Xh, dwInstance=%.08lXh",
  62. gpag->htaskInput, dwInstance);
  63. #endif // !WIN32
  64. if (!SetMessageQueue(64))
  65. {
  66. DPF(0, "!mapWaveInputConvertProc: SetMessageQueue() failed!");
  67. return (0L);
  68. }
  69. #ifdef WIN32
  70. //
  71. // Make sure we have a message queue for this thread and signal the
  72. // caller when we're ready to go
  73. //
  74. GetDesktopWindow(); // Makes sure we've got a message queue
  75. SetEvent(LongToHandle(dwInstance));
  76. #endif
  77. //
  78. //
  79. //
  80. while (GetMessage(&msg, NULL, 0, 0))
  81. {
  82. #ifdef DEBUG
  83. if (gpag->fFaultAndDie)
  84. {
  85. if ((rand() & 0x7) == 0)
  86. {
  87. gpag->fFaultAndDie = (BOOL)*((LPBYTE)0);
  88. DPF(1, "mapWaveInputConvertProc: fault was ignored...");
  89. gpag->fFaultAndDie = TRUE;
  90. }
  91. }
  92. #endif
  93. //
  94. // if not a 'data' message, then translate and dispatch it...
  95. //
  96. if (msg.message != WIM_DATA)
  97. {
  98. DPF(1, "mapWaveInputConvertProc: ignoring message [%.04Xh]", msg.message);
  99. TranslateMessage(&msg);
  100. DispatchMessage(&msg);
  101. continue;
  102. }
  103. //
  104. // lParam is the waveheader of the shadow buffer
  105. //
  106. pwhShadow = (LPWAVEHDR)msg.lParam;
  107. //
  108. // client wave header is user data of shadow wave header
  109. // the stream header for this client/shadow pair is in the client's
  110. // 'reserved' member
  111. //
  112. // and finally, our stream header's dwUser member contains a
  113. // reference to our mapping stream instance data.
  114. //
  115. pwh = (LPWAVEHDR)pwhShadow->dwUser;
  116. pash = (LPACMSTREAMHEADER)pwh->reserved;
  117. pms = (LPMAPSTREAM)pash->dwUser;
  118. DPF(4, "mapWaveInputConvertProc: WIM_DATA htask=%.04Xh, pms=%.08lXh, pwh=%.08lXh, pwhShadow=%.08lXh",
  119. pms->htaskInput, pms, pwh, pwhShadow);
  120. //
  121. // do the conversion (if there is data in the input buffer)
  122. //
  123. pash->cbDstLengthUsed = 0L;
  124. if (0L != pwhShadow->dwBytesRecorded)
  125. {
  126. pash->pbSrc = pwhShadow->lpData;
  127. pash->cbSrcLength = pwhShadow->dwBytesRecorded;
  128. pash->pbDst = pwh->lpData;
  129. ////////////pash->cbDstLength = pwh->dwBufferLength;
  130. mmr = acmStreamConvert(pms->has, pash, ACM_STREAMCONVERTF_BLOCKALIGN);
  131. if (MMSYSERR_NOERROR != mmr)
  132. {
  133. DPF(0, "!mapWaveInputConvertProc: conversion failed! mmr=%.04Xh, pms=%.08lXh", mmr, pms);
  134. pash->cbDstLengthUsed = 0L;
  135. }
  136. else if (pash->cbSrcLength != pash->cbSrcLengthUsed)
  137. {
  138. DPF(1, "mapWaveInputConvertProc: discarding %lu bytes of input! pms=%.08lXh",
  139. pash->cbSrcLength - pash->cbSrcLengthUsed, pms);
  140. }
  141. }
  142. if (0L == pash->cbDstLengthUsed)
  143. {
  144. DPF(1, "mapWaveInputConvertProc: nothing converted--no data in input buffer. pms=%.08lXh", pms);
  145. }
  146. //
  147. // update the 'real' header and send the WIM_DATA callback
  148. //
  149. //
  150. pwh->dwBytesRecorded = pash->cbDstLengthUsed;
  151. pwh->dwFlags |= WHDR_DONE;
  152. pwh->dwFlags &= ~WHDR_INQUEUE;
  153. mapWaveDriverCallback(pms, WIM_DATA, (DWORD_PTR)pwh, 0L);
  154. #ifdef WIN32
  155. if (InterlockedDecrement((PLONG)&pms->nOutstanding) == 0) {
  156. SetEvent(pms->hStoppedEvent);
  157. }
  158. #endif // WIN32
  159. }
  160. #ifndef WIN32
  161. DPF(1, "mapWaveInputConvertProc: being KILLED htask=%.04Xh", gpag->htaskInput);
  162. #endif // !WIN32
  163. return (0L);
  164. } // mapWaveInputConvertProc()
  165. //--------------------------------------------------------------------------;
  166. //
  167. // DWORD widmMapperStatus
  168. //
  169. // Description:
  170. //
  171. //
  172. // Arguments:
  173. // LPMAPSTREAM pms:
  174. //
  175. // DWORD dwStatus:
  176. //
  177. // LPDWORD pdw:
  178. //
  179. // Return (DWORD):
  180. //
  181. // History:
  182. // 08/13/93 cjp [curtisp]
  183. //
  184. //--------------------------------------------------------------------------;
  185. DWORD FNLOCAL widmMapperStatus
  186. (
  187. LPMAPSTREAM pms,
  188. DWORD dwStatus,
  189. LPDWORD pdw
  190. )
  191. {
  192. MMRESULT mmr;
  193. // V_WPOINTER(pdw, sizeof(DWORD), MMSYSERR_INVALPARAM);
  194. if ((NULL == pms) || (NULL == pdw))
  195. {
  196. return (MMSYSERR_INVALPARAM);
  197. }
  198. //
  199. //
  200. //
  201. switch (dwStatus)
  202. {
  203. case WAVEIN_MAPPER_STATUS_DEVICE:
  204. {
  205. UINT uId = (UINT)(-1); // Invalid value
  206. mmr = waveInGetID(pms->hwiReal, &uId);
  207. if (MMSYSERR_NOERROR != mmr)
  208. {
  209. return (mmr);
  210. }
  211. *pdw = uId;
  212. return (MMSYSERR_NOERROR);
  213. }
  214. case WAVEIN_MAPPER_STATUS_MAPPED:
  215. *pdw = (NULL != pms->has);
  216. return (MMSYSERR_NOERROR);
  217. case WAVEIN_MAPPER_STATUS_FORMAT:
  218. if (NULL != pms->has)
  219. _fmemcpy(pdw, pms->pwfxReal, sizeof(PCMWAVEFORMAT));
  220. else
  221. _fmemcpy(pdw, pms->pwfxClient, sizeof(PCMWAVEFORMAT));
  222. ((LPWAVEFORMATEX)pdw)->cbSize = 0;
  223. return (MMSYSERR_NOERROR);
  224. }
  225. //
  226. //
  227. //
  228. return (MMSYSERR_NOTSUPPORTED);
  229. } // widmMapperStatus()
  230. //--------------------------------------------------------------------------;
  231. //
  232. // DWORD widMessage
  233. //
  234. // Description:
  235. // This function conforms to the standard Wave Input driver message
  236. // procedure (widMessage), which is documented in mmddk.d.
  237. //
  238. // Arguments:
  239. // UINT uId:
  240. //
  241. // UINT uMsg:
  242. //
  243. // DWORD dwUser:
  244. //
  245. // DWORD dwParam1:
  246. //
  247. // DWORD dwParam2:
  248. //
  249. // Return (DWORD):
  250. //
  251. //
  252. // History:
  253. // 11/15/92 cjp [curtisp]
  254. //
  255. //--------------------------------------------------------------------------;
  256. EXTERN_C DWORD FNEXPORT widMessage
  257. (
  258. UINT uId,
  259. UINT uMsg,
  260. DWORD_PTR dwUser,
  261. DWORD_PTR dwParam1,
  262. DWORD_PTR dwParam2
  263. )
  264. {
  265. #ifndef WIN32 // Doesn't work for multithread
  266. static short fSem = 0;
  267. #endif // !WIN32
  268. LPMAPSTREAM pms; // pointer to per-instance info structure
  269. DWORD dw;
  270. if (!gpag->fEnabled)
  271. {
  272. DPF(1, "widMessage: called while disabled!");
  273. return ((WIDM_GETNUMDEVS == uMsg) ? 0L : MMSYSERR_NOTENABLED);
  274. }
  275. #ifndef WIN32
  276. //
  277. // we call back into the mmsystem wave APIs so protect ourself
  278. // from being re-entered!
  279. //
  280. if (fSem)
  281. {
  282. DPF(0, "!widMessage(uMsg=%u, dwUser=%.08lXh) being reentered! fSem=%d", uMsg, dwUser, fSem);
  283. // return (MMSYSERR_NOTSUPPORTED);
  284. }
  285. #endif // !WIN32
  286. pms = (LPMAPSTREAM)dwUser;
  287. switch (uMsg)
  288. {
  289. case WIDM_GETNUMDEVS:
  290. return (1L);
  291. case WIDM_GETDEVCAPS:
  292. return mapWaveGetDevCaps(TRUE, (LPWAVEOUTCAPS)dwParam1, (UINT)dwParam2);
  293. case WIDM_OPEN:
  294. #ifndef WIN32
  295. fSem++;
  296. DPF(1, "**** >> WIDM_OPEN(uMsg=%u, dwUser=%.08lXh, fSem=%d)", uMsg, dwUser, fSem);
  297. #endif // !WIN32
  298. //
  299. // dwParam1 contains a pointer to a WAVEOPENDESC
  300. // dwParam2 contains wave driver specific flags in the LOWORD
  301. // and generic driver flags in the HIWORD
  302. //
  303. dw = mapWaveOpen(TRUE, uId, dwUser, (LPWAVEOPENDESC)dwParam1, (DWORD)(PtrToLong((PVOID)dwParam2)) );
  304. #ifndef WIN32
  305. fSem--;
  306. DPF(1, "**** << WIDM_OPEN(uMsg=%u, dwUser=%.08lXh, *dwUser=%.08lXh, fSem=%d)", uMsg, dwUser, *(LPDWORD)dwUser, fSem);
  307. #endif // !WIN32
  308. return (dw);
  309. case WIDM_CLOSE:
  310. return (mapWaveClose(pms));
  311. case WIDM_PREPARE:
  312. return (mapWavePrepareHeader(pms, (LPWAVEHDR)dwParam1));
  313. case WIDM_UNPREPARE:
  314. return (mapWaveUnprepareHeader(pms, (LPWAVEHDR)dwParam1));
  315. case WIDM_ADDBUFFER:
  316. return (mapWaveWriteBuffer(pms, (LPWAVEHDR)dwParam1));
  317. case WIDM_START:
  318. DPF(4, "WIDM_START received...");
  319. return waveInStart(pms->hwiReal);
  320. case WIDM_STOP:
  321. DPF(4, "WIDM_STOP received..");
  322. dw = waveInStop(pms->hwiReal);
  323. #pragma message("----try to kill DirectedYield..")
  324. //
  325. // yield enough to get all input messages processed
  326. //
  327. if (pms->htaskInput)
  328. {
  329. #ifdef WIN32
  330. ResetEvent(pms->hStoppedEvent);
  331. if (pms->nOutstanding != 0) {
  332. WaitForSingleObject(pms->hStoppedEvent, INFINITE);
  333. }
  334. #else
  335. if (IsTask(pms->htaskInput))
  336. {
  337. DirectedYield(pms->htaskInput);
  338. }
  339. else
  340. {
  341. DPF(0, "!WIDM_STOP: pms=%.08lXh, htask=%.04Xh is not valid!",
  342. pms, pms->htaskInput);
  343. pms->htaskInput = NULL;
  344. }
  345. #endif // !WIN32
  346. }
  347. return (dw);
  348. case WIDM_RESET:
  349. DPF(4, "WIDM_RESET received...");
  350. dw = waveInReset(pms->hwiReal);
  351. //
  352. // yield enough to get all input messages processed
  353. //
  354. if (pms->htaskInput)
  355. {
  356. #ifdef WIN32
  357. ResetEvent(pms->hStoppedEvent);
  358. if (pms->nOutstanding != 0) {
  359. WaitForSingleObject(pms->hStoppedEvent, INFINITE);
  360. }
  361. #else
  362. if (IsTask(pms->htaskInput))
  363. {
  364. DirectedYield(pms->htaskInput);
  365. }
  366. else
  367. {
  368. DPF(0, "!WIDM_RESET: pms=%.08lXh, htask=%.04Xh is not valid!",
  369. pms, pms->htaskInput);
  370. pms->htaskInput = NULL;
  371. }
  372. #endif // !WIN32
  373. }
  374. return (dw);
  375. case WIDM_GETPOS:
  376. return mapWaveGetPosition(pms, (LPMMTIME)dwParam1, (UINT)dwParam2);
  377. case WIDM_MAPPER_STATUS:
  378. dw = widmMapperStatus(pms, (DWORD)(PtrToLong((PVOID)dwParam1)), (LPDWORD)dwParam2);
  379. return (dw);
  380. #if (WINVER >= 0x0400)
  381. case DRVM_MAPPER_RECONFIGURE:
  382. mapDriverDisable(NULL);
  383. mapDriverEnable(NULL);
  384. return (0);
  385. #endif
  386. }
  387. if (!pms || !pms->hwiReal)
  388. return (MMSYSERR_NOTSUPPORTED);
  389. return waveInMessage(pms->hwiReal, uMsg, dwParam1, dwParam2);
  390. } // widMessage()