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.

352 lines
9.2 KiB

  1. //==========================================================================;
  2. //
  3. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  4. // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  5. // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  6. // PURPOSE.
  7. //
  8. // Copyright (c) 1992 - 1994 Microsoft Corporation. All Rights Reserved.
  9. //
  10. //--------------------------------------------------------------------------;
  11. //
  12. // waveio.c
  13. //
  14. // Description:
  15. //
  16. //
  17. //
  18. //==========================================================================;
  19. #include <windows.h>
  20. #include <windowsx.h>
  21. #include <mmsystem.h>
  22. #include <mmreg.h>
  23. #include <memory.h>
  24. #include "appport.h"
  25. #include "waveio.h"
  26. #include "debug.h"
  27. //--------------------------------------------------------------------------;
  28. //
  29. // WIOERR wioFileClose
  30. //
  31. // Description:
  32. //
  33. //
  34. // Arguments:
  35. // LPWAVEIOCB pwio:
  36. //
  37. // DWORD fdwClose:
  38. //
  39. // Return (WIOERR):
  40. //
  41. //--------------------------------------------------------------------------;
  42. WIOERR WIOAPI wioFileClose
  43. (
  44. LPWAVEIOCB pwio,
  45. DWORD fdwClose
  46. )
  47. {
  48. //
  49. // validate a couple of things...
  50. //
  51. if (NULL == pwio)
  52. return (WIOERR_BADPARAM);
  53. //
  54. // get rid of stuff...
  55. //
  56. // wioStopWave(pwio);
  57. if (NULL != pwio->hmmio)
  58. {
  59. mmioClose(pwio->hmmio, 0);
  60. }
  61. // FreeWaveHeaders(lpwio);
  62. #if 0
  63. if (pwio->pInfo)
  64. riffFreeINFO(&(lpwio->pInfo));
  65. if (pwio->pDisp)
  66. riffFreeDISP(&(lpwio->pDisp));
  67. #endif
  68. if (NULL != pwio->pwfx)
  69. GlobalFreePtr(pwio->pwfx);
  70. _fmemset(pwio, 0, sizeof(*pwio));
  71. return (WIOERR_NOERROR);
  72. } // wioFileClose()
  73. //--------------------------------------------------------------------------;
  74. //
  75. // WIOERR wioFileOpen
  76. //
  77. // Description:
  78. //
  79. //
  80. // Arguments:
  81. // LPWAVEIOCB pwio:
  82. //
  83. // LPCTSTR pszFilePath:
  84. //
  85. // DWORD fdwOpen:
  86. //
  87. // Return (WIOERR):
  88. //
  89. //
  90. //--------------------------------------------------------------------------;
  91. WIOERR WIOAPI wioFileOpen
  92. (
  93. LPWAVEIOCB pwio,
  94. LPCTSTR pszFilePath,
  95. DWORD fdwOpen
  96. )
  97. {
  98. UINT u;
  99. TCHAR ach[255];
  100. WIOERR werr;
  101. HMMIO hmmio;
  102. MMCKINFO ckRIFF;
  103. MMCKINFO ck;
  104. DWORD dw;
  105. //
  106. // validate a couple of things...
  107. //
  108. if (NULL == pwio)
  109. return (WIOERR_BADPARAM);
  110. //
  111. // default our error return (assume the worst)
  112. //
  113. _fmemset(pwio, 0, sizeof(*pwio));
  114. werr = WIOERR_FILEERROR;
  115. pwio->dwFlags = fdwOpen;
  116. //
  117. // first try to open the file, etc.. open the given file for reading
  118. // using buffered I/O
  119. //
  120. hmmio = mmioOpen((LPTSTR)pszFilePath, NULL, MMIO_READ | MMIO_ALLOCBUF);
  121. if (NULL == hmmio)
  122. goto wio_Open_Error;
  123. pwio->hmmio = hmmio;
  124. //
  125. // locate a 'WAVE' form type...
  126. //
  127. ckRIFF.fccType = mmioFOURCC('W', 'A', 'V', 'E');
  128. if (mmioDescend(hmmio, &ckRIFF, NULL, MMIO_FINDRIFF))
  129. goto wio_Open_Error;
  130. //
  131. // we found a WAVE chunk--now go through and get all subchunks that
  132. // we know how to deal with...
  133. //
  134. pwio->dwDataSamples = (DWORD)-1L;
  135. #if 0
  136. if (lrt=riffInitINFO(&wio.pInfo))
  137. {
  138. lr=lrt;
  139. goto wio_Open_Error;
  140. }
  141. #endif
  142. //
  143. //
  144. //
  145. while (MMSYSERR_NOERROR == mmioDescend(hmmio, &ck, &ckRIFF, 0))
  146. {
  147. //
  148. // quickly check for corrupt RIFF file--don't ascend past end!
  149. //
  150. if ((ck.dwDataOffset + ck.cksize) > (ckRIFF.dwDataOffset + ckRIFF.cksize))
  151. {
  152. DPF(1, "wioFileOpen() FILE MIGHT BE CORRUPT!");
  153. DPF(1, " ckRIFF.dwDataOffset: %lu", ckRIFF.dwDataOffset);
  154. DPF(1, " ckRIFF.cksize: %lu", ckRIFF.cksize);
  155. DPF(1, " ck.dwDataOffset: %lu", ck.dwDataOffset);
  156. DPF(1, " ck.cksize: %lu", ck.cksize);
  157. wsprintf(ach, TEXT("This wave file might be corrupt. The RIFF chunk.ckid '%.08lX' (data offset at %lu) specifies a cksize of %lu that extends beyond what the RIFF header cksize of %lu allows. Attempt to load?"),
  158. ck.ckid, ck.dwDataOffset, ck.cksize, ckRIFF.cksize);
  159. u = MessageBox(NULL, ach, TEXT("wioFileOpen"),
  160. MB_YESNO | MB_ICONEXCLAMATION | MB_TASKMODAL);
  161. if (IDNO == u)
  162. {
  163. werr = WIOERR_BADFILE;
  164. goto wio_Open_Error;
  165. }
  166. }
  167. switch (ck.ckid)
  168. {
  169. case mmioFOURCC('L', 'I', 'S', 'T'):
  170. if (ck.fccType == mmioFOURCC('I', 'N', 'F', 'O'))
  171. {
  172. #if 0
  173. if(lrt=riffReadINFO(hmmio, &ck, wio.pInfo))
  174. {
  175. lr=lrt;
  176. goto wio_Open_Error;
  177. }
  178. #endif
  179. }
  180. break;
  181. case mmioFOURCC('D', 'I', 'S', 'P'):
  182. #if 0
  183. riffReadDISP(hmmio, &ck, &(wio.pDisp));
  184. #endif
  185. break;
  186. case mmioFOURCC('f', 'm', 't', ' '):
  187. //
  188. // !?! another format chunk !?!
  189. //
  190. if (NULL != pwio->pwfx)
  191. break;
  192. //
  193. // get size of the format chunk, allocate and lock memory
  194. // for it. we always alloc a complete extended format header
  195. // (even for PCM headers that do not have the cbSize field
  196. // defined--we just set it to zero).
  197. //
  198. dw = ck.cksize;
  199. if (dw < sizeof(WAVEFORMATEX))
  200. dw = sizeof(WAVEFORMATEX);
  201. pwio->pwfx = (LPWAVEFORMATEX)GlobalAllocPtr(GHND, dw);
  202. if (NULL == pwio->pwfx)
  203. {
  204. werr = WIOERR_NOMEM;
  205. goto wio_Open_Error;
  206. }
  207. //
  208. // read the format chunk
  209. //
  210. werr = WIOERR_FILEERROR;
  211. dw = ck.cksize;
  212. if (mmioRead(hmmio, (HPSTR)pwio->pwfx, dw) != (LONG)dw)
  213. goto wio_Open_Error;
  214. break;
  215. case mmioFOURCC('d', 'a', 't', 'a'):
  216. //
  217. // !?! multiple data chunks !?!
  218. //
  219. if (0L != pwio->dwDataBytes)
  220. break;
  221. //
  222. // just hang on to the total length in bytes of this data
  223. // chunk.. and the offset to the start of the data
  224. //
  225. pwio->dwDataBytes = ck.cksize;
  226. pwio->dwDataOffset = ck.dwDataOffset;
  227. break;
  228. case mmioFOURCC('f', 'a', 'c', 't'):
  229. //
  230. // !?! multiple fact chunks !?!
  231. //
  232. if (-1L != pwio->dwDataSamples)
  233. break;
  234. //
  235. // read the first dword in the fact chunk--it's the only
  236. // info we need (and is currently the only info defined for
  237. // the fact chunk...)
  238. //
  239. // if this fails, dwDataSamples will remain -1 so we will
  240. // deal with it later...
  241. //
  242. mmioRead(hmmio, (HPSTR)&pwio->dwDataSamples, sizeof(DWORD));
  243. break;
  244. }
  245. //
  246. // step up to prepare for next chunk..
  247. //
  248. mmioAscend(hmmio, &ck, 0);
  249. }
  250. //
  251. // if no fmt chunk was found, then die!
  252. //
  253. if (NULL == pwio->pwfx)
  254. {
  255. werr = WIOERR_ERROR;
  256. goto wio_Open_Error;
  257. }
  258. //
  259. // all wave files other than PCM are _REQUIRED_ to have a fact chunk
  260. // telling the number of samples that are contained in the file. it
  261. // is optional for PCM (and if not present, we compute it here).
  262. //
  263. // if the file is not PCM and the fact chunk is not found, then fail!
  264. //
  265. if (-1L == pwio->dwDataSamples)
  266. {
  267. if (WAVE_FORMAT_PCM == pwio->pwfx->wFormatTag)
  268. {
  269. pwio->dwDataSamples = pwio->dwDataBytes / pwio->pwfx->nBlockAlign;
  270. }
  271. else
  272. {
  273. //
  274. // !!! HACK HACK HACK !!!
  275. //
  276. // although this should be considered an invalid wave file, we
  277. // will bring up a message box describing the error--hopefully
  278. // people will start realizing that something is missing???
  279. //
  280. u = MessageBox(NULL, TEXT("This wave file does not have a 'fact' chunk and requires one! This is completely invalid and MUST be fixed! Attempt to load it anyway?"),
  281. TEXT("wioFileOpen"), MB_YESNO | MB_ICONEXCLAMATION | MB_TASKMODAL);
  282. if (IDNO == u)
  283. {
  284. werr = WIOERR_BADFILE;
  285. goto wio_Open_Error;
  286. }
  287. //
  288. // !!! need to hack stuff in here !!!
  289. //
  290. pwio->dwDataSamples = 0L;
  291. }
  292. }
  293. //
  294. // cool! no problems..
  295. //
  296. return (WIOERR_NOERROR);
  297. //
  298. // return error (after minor cleanup)
  299. //
  300. wio_Open_Error:
  301. wioFileClose(pwio, 0L);
  302. return (werr);
  303. } // wioFileOpen()