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.

783 lines
21 KiB

  1. /*-----------------------------------------------------------------------------+
  2. | RIFFDISP.C |
  3. | |
  4. | (C) Copyright Microsoft Corporation 1991. All rights reserved. |
  5. | |
  6. | Revision History |
  7. | Oct-1992 MikeTri Ported to WIN32 / WIN16 common code |
  8. | |
  9. +-----------------------------------------------------------------------------*/
  10. #include <windows.h>
  11. #include <windowsx.h>
  12. #include <mmsystem.h>
  13. #include <commdlg.h>
  14. #ifdef WIN16
  15. #include "port16.h"
  16. #endif
  17. #include "mplayer.h"
  18. #include "riffdisp.h"
  19. static HWND hwndPreview;
  20. static HANDLE hdibPreview;
  21. static TCHAR achPreview[80];
  22. static HFONT hfontPreview;
  23. static HINSTANCE hMSVideo;
  24. typedef HANDLE HDRAWDIB;
  25. typedef HDRAWDIB (FAR PASCAL *PFNDRAWDIBOPEN)(void);
  26. typedef BOOL (FAR PASCAL *PFNDRAWDIBCLOSE)(HDRAWDIB hdd);
  27. typedef BOOL (FAR PASCAL *PFNDRAWDIBDRAW)(HDRAWDIB hdd,HDC hdc,int xDst,int yDst,int dxDst,int dyDst,LPBITMAPINFOHEADER lpbi,LPVOID lpBits,int xSrc,int ySrc,int dxSrc,int dySrc,UINT wFlags);
  28. static HDRAWDIB hdd;
  29. static PFNDRAWDIBOPEN pfnDrawDibOpen;
  30. static PFNDRAWDIBCLOSE pfnDrawDibClose;
  31. static PFNDRAWDIBDRAW pfnDrawDibDraw;
  32. #define GetHInstance() (HINSTANCE)(SELECTOROF((LPVOID)&hwndPreview))
  33. /***************************************************************************
  34. *
  35. ****************************************************************************/
  36. //#define FOURCC_RIFF mmioFOURCC('R','I','F','F')
  37. #define FOURCC_INFO mmioFOURCC('I','N','F','O')
  38. #define FOURCC_DISP mmioFOURCC('D','I','S','P')
  39. #define FOURCC_INAM mmioFOURCC('I','N','A','M')
  40. #define FOURCC_ISBJ mmioFOURCC('I','S','B','J')
  41. BOOL PreviewOpen(HWND hwnd);
  42. BOOL PreviewFile(HWND hwnd, LPTSTR szFile);
  43. BOOL PreviewPaint(HWND hwnd);
  44. BOOL PreviewClose(HWND hwnd);
  45. HANDLE ReadDisp(LPTSTR lpszFile, int cf, LPTSTR pv, int iLen);
  46. HANDLE ReadInfo(LPTSTR lpszFile, FOURCC fcc, LPTSTR pv, int iLen);
  47. HANDLE GetRiffDisp(LPTSTR lpszFile, LPTSTR szText, int iLen);
  48. /***************************************************************************
  49. *
  50. ****************************************************************************/
  51. BOOL PreviewOpen(HWND hwnd)
  52. {
  53. LOGFONT lf;
  54. UINT w;
  55. if (hwndPreview)
  56. return FALSE;
  57. hwndPreview = hwnd;
  58. w = SetErrorMode(SEM_NOOPENFILEERRORBOX);
  59. hMSVideo = LoadLibrary(TEXT("MSVIDEO.DLL"));
  60. SetErrorMode(w);
  61. #ifdef WIN32
  62. if (hMSVideo != NULL)
  63. #else
  64. if (hMSVideo > HINSTANCE_ERROR)
  65. #endif
  66. {
  67. pfnDrawDibOpen = (PFNDRAWDIBOPEN)GetProcAddress(hMSVideo, ANSI_TEXT("DrawDibOpen"));
  68. pfnDrawDibClose = (PFNDRAWDIBCLOSE)GetProcAddress(hMSVideo, ANSI_TEXT("DrawDibClose"));
  69. pfnDrawDibDraw = (PFNDRAWDIBDRAW)GetProcAddress(hMSVideo, ANSI_TEXT("DrawDibDraw"));
  70. if (pfnDrawDibOpen)
  71. hdd = pfnDrawDibOpen();
  72. }
  73. SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lf), (LPVOID)&lf, 0);
  74. hfontPreview = CreateFontIndirect(&lf);
  75. }
  76. /***************************************************************************
  77. *
  78. ****************************************************************************/
  79. BOOL PreviewClose(HWND hwnd)
  80. {
  81. if (hwndPreview != hwnd)
  82. return FALSE;
  83. if (hdibPreview)
  84. GlobalFree(hdibPreview);
  85. if (hfontPreview)
  86. DeleteObject(hfontPreview);
  87. if (hdd)
  88. pfnDrawDibClose(hdd);
  89. #ifdef WIN32
  90. if (hMSVideo != NULL)
  91. #else
  92. if (hMSVideo >= HINSTANCE_ERROR)
  93. #endif
  94. FreeLibrary(hMSVideo);
  95. achPreview[0] = 0;
  96. hdd = NULL;
  97. hMSVideo = NULL;
  98. hwndPreview = NULL;
  99. hdibPreview = NULL;
  100. hfontPreview = NULL;
  101. }
  102. /***************************************************************************
  103. *
  104. ****************************************************************************/
  105. BOOL PreviewFile(HWND hwnd, LPTSTR szFile)
  106. {
  107. if (hwndPreview != hwnd)
  108. return FALSE;
  109. achPreview[0] = 0;
  110. if (hdibPreview)
  111. GlobalFree(hdibPreview);
  112. hdibPreview = NULL;
  113. if (szFile)
  114. {
  115. hdibPreview = GetRiffDisp(szFile, achPreview, BYTE_COUNT(achPreview));
  116. }
  117. PreviewPaint(hwnd);
  118. return TRUE;
  119. }
  120. /***************************************************************************
  121. *
  122. ****************************************************************************/
  123. BOOL PreviewPaint(HWND hwnd)
  124. {
  125. RECT rc;
  126. RECT rcPreview;
  127. RECT rcImage;
  128. RECT rcText;
  129. HDC hdc;
  130. HBRUSH hbr;
  131. int dx;
  132. int dy;
  133. LPBITMAPINFOHEADER lpbi;
  134. if (hwndPreview != hwnd)
  135. return FALSE;
  136. //
  137. // locate the preview in the lower corner of the dialog (below the
  138. // cancel button)
  139. //
  140. GetClientRect(hwnd, &rcPreview);
  141. GetWindowRect(GetDlgItem(hwnd, IDCANCEL), &rc);
  142. ScreenToClient(hwnd, (LPPOINT)&rc);
  143. ScreenToClient(hwnd, (LPPOINT)&rc+1);
  144. rcPreview.top = rc.bottom + (rc.bottom - rc.top) + 12;
  145. rcPreview.left = rc.left;
  146. rcPreview.right = rc.right;
  147. rcPreview.bottom -= 4; // leave a little room at the bottom
  148. hdc = GetDC(hwnd);
  149. #ifdef WIN32
  150. hbr = (HBRUSH)DefWindowProc(hwnd, WM_CTLCOLORDLG, (WPARAM)hdc, (LPARAM)hwnd);
  151. #else
  152. hbr = (HBRUSH)DefWindowProc(hwnd, WM_CTLCOLOR, (WPARAM)hdc, MAKELONG(hwnd, CTLCOLOR_DLG));
  153. #endif
  154. SelectObject(hdc, hfontPreview);
  155. SetStretchBltMode(hdc, COLORONCOLOR);
  156. InflateRect(&rcPreview, 4, 1);
  157. FillRect(hdc, &rcPreview, hbr);
  158. IntersectClipRect(hdc, rcPreview.left, rcPreview.top, rcPreview.right, rcPreview.bottom);
  159. InflateRect(&rcPreview, -4, -1);
  160. //
  161. // compute the text rect, using DrawText
  162. //
  163. rcText = rcPreview;
  164. rcText.bottom = rcText.top;
  165. DrawText(hdc, achPreview, -1, &rcText, DT_CALCRECT|DT_LEFT|DT_WORDBREAK);
  166. //
  167. // compute the image size
  168. //
  169. if (hdibPreview && hdd)
  170. {
  171. lpbi = GlobalLock(hdibPreview);
  172. //
  173. // DISP(CF_DIB) chunks are messed up they contain a DIB file! not
  174. // a CF_DIB, skip over the header if it is there.
  175. //
  176. if (lpbi->biSize != sizeof(BITMAPINFOHEADER))
  177. lpbi = (LPBITMAPINFOHEADER)((LPBYTE)lpbi + sizeof(BITMAPFILEHEADER));
  178. rcImage = rcPreview;
  179. //
  180. // if wider than preview area scale to fit
  181. //
  182. if ((int)lpbi->biWidth > rcImage.right - rcImage.left)
  183. {
  184. rcImage.bottom = rcImage.top + MulDiv((int)lpbi->biHeight,rcImage.right-rcImage.left,(int)lpbi->biWidth);
  185. }
  186. //
  187. // if x2 will fit then use it
  188. //
  189. else if ((int)lpbi->biWidth * 2 < rcImage.right - rcImage.left)
  190. {
  191. rcImage.right = rcImage.left + (int)lpbi->biWidth*2;
  192. rcImage.bottom = rcImage.top + (int)lpbi->biHeight*2;
  193. }
  194. //
  195. // else center the image in the preview area
  196. //
  197. else
  198. {
  199. rcImage.right = rcImage.left + (int)lpbi->biWidth;
  200. rcImage.bottom = rcImage.top + (int)lpbi->biHeight;
  201. }
  202. if (rcImage.bottom > rcPreview.bottom - (rcText.bottom - rcText.top))
  203. {
  204. rcImage.bottom = rcPreview.bottom - (rcText.bottom - rcText.top);
  205. rcImage.right = rcPreview.left +
  206. MulDiv((int)lpbi->biWidth,
  207. rcImage.bottom-rcImage.top,
  208. (int)lpbi->biHeight);
  209. rcImage.left = rcPreview.left;
  210. }
  211. }
  212. else
  213. {
  214. SetRectEmpty(&rcImage);
  215. }
  216. //
  217. // now center
  218. //
  219. dx = ((rcPreview.right - rcPreview.left) - (rcText.right - rcText.left))/2;
  220. OffsetRect(&rcText, dx, 0);
  221. dx = ((rcPreview.right - rcPreview.left) - (rcImage.right - rcImage.left))/2;
  222. OffsetRect(&rcImage, dx, 0);
  223. dy = rcPreview.bottom - rcPreview.top;
  224. dy -= rcImage.bottom - rcImage.top;
  225. dy -= rcText.bottom - rcText.top;
  226. if (dy < 0)
  227. dy = 0;
  228. else
  229. dy = dy / 2;
  230. OffsetRect(&rcImage, 0, dy);
  231. OffsetRect(&rcText, 0, dy + rcImage.bottom - rcImage.top + 2);
  232. //
  233. // now draw
  234. //
  235. DrawText(hdc, achPreview, -1, &rcText, DT_LEFT|DT_WORDBREAK);
  236. if (hdibPreview && hdd)
  237. {
  238. pfnDrawDibDraw(hdd,
  239. hdc,
  240. rcImage.left,
  241. rcImage.top,
  242. rcImage.right - rcImage.left,
  243. rcImage.bottom - rcImage.top,
  244. lpbi,
  245. NULL,
  246. 0,
  247. 0,
  248. -1,
  249. -1,
  250. 0);
  251. InflateRect(&rcImage, 1, 1);
  252. FrameRect(hdc, &rcImage, GetStockObject(BLACK_BRUSH));
  253. }
  254. ReleaseDC(hwnd, hdc);
  255. return TRUE;
  256. }
  257. /***************************************************************************
  258. *
  259. ****************************************************************************/
  260. static UINT (FAR PASCAL *lpfnOldHook)(HWND, unsigned, WPARAM, LPARAM);
  261. /* Combo boxes */
  262. #define cmb1 0x0470
  263. #define cmb2 0x0471
  264. /* Listboxes */
  265. #define lst1 0x0460
  266. #define lst2 0x0461
  267. /* Edit controls */
  268. #define edt1 0x0480
  269. #define ID_TIMER 1234
  270. #define PREVIEWWAIT 1000
  271. UINT FAR PASCAL _EXPORT GetFileNamePreviewHook(HWND hwnd, unsigned msg, WPARAM wParam, LPARAM lParam)
  272. {
  273. int i;
  274. TCHAR ach[80];
  275. UINT Code;
  276. switch (msg) {
  277. case WM_COMMAND:
  278. Code = GET_WM_COMMAND_CMD(wParam,lParam);
  279. switch (LOWORD(wParam)) {
  280. case lst1:
  281. if (Code == LBN_SELCHANGE)
  282. {
  283. KillTimer(hwnd, ID_TIMER);
  284. SetTimer(hwnd, ID_TIMER, PREVIEWWAIT, NULL);
  285. }
  286. break;
  287. case IDOK:
  288. case IDCANCEL:
  289. KillTimer(hwnd, ID_TIMER);
  290. PreviewFile(hwnd, NULL);
  291. break;
  292. case cmb1:
  293. case cmb2:
  294. case lst2:
  295. if (Code == LBN_SELCHANGE)
  296. {
  297. KillTimer(hwnd, ID_TIMER);
  298. PreviewFile(hwnd, NULL);
  299. }
  300. break;
  301. }
  302. break;
  303. case WM_TIMER:
  304. if (wParam == ID_TIMER)
  305. {
  306. KillTimer(hwnd, ID_TIMER);
  307. ach[0] = 0;
  308. i = (int)SendDlgItemMessage(hwnd, lst1, LB_GETCURSEL, 0, 0L);
  309. SendDlgItemMessage(hwnd, lst1, LB_GETTEXT, i, (LONG)(LPTSTR)ach);
  310. PreviewFile(hwnd, ach);
  311. return TRUE;
  312. }
  313. break;
  314. case WM_QUERYNEWPALETTE:
  315. case WM_PALETTECHANGED:
  316. case WM_PAINT:
  317. PreviewPaint(hwnd);
  318. break;
  319. case WM_INITDIALOG:
  320. PreviewOpen(hwnd);
  321. break;
  322. case WM_DESTROY:
  323. PreviewClose(hwnd);
  324. break;
  325. }
  326. if (lpfnOldHook)
  327. return (*lpfnOldHook)(hwnd, msg, wParam, lParam);
  328. else
  329. return FALSE;
  330. }
  331. /***************************************************************************
  332. *
  333. ****************************************************************************/
  334. BOOL FAR PASCAL GetOpenFileNamePreview(LPOPENFILENAME lpofn)
  335. {
  336. BOOL fHook;
  337. BOOL f;
  338. if (hwndPreview)
  339. return GetOpenFileName(lpofn);
  340. fHook = (BOOL)(lpofn->Flags & OFN_ENABLEHOOK);
  341. if (fHook)
  342. lpfnOldHook = lpofn->lpfnHook;
  343. lpofn->lpfnHook = (LPOFNHOOKPROC)MakeProcInstance((FARPROC)GetFileNamePreviewHook, GetHInstance());
  344. lpofn->Flags |= OFN_ENABLEHOOK;
  345. f = GetOpenFileName(lpofn);
  346. #ifndef WIN32
  347. FreeProcInstance((FARPROC)lpofn->lpfnHook);
  348. #endif
  349. if (fHook)
  350. lpofn->lpfnHook = lpfnOldHook;
  351. else
  352. lpofn->Flags &= ~OFN_ENABLEHOOK;
  353. return f;
  354. }
  355. /****************************************************************************
  356. *
  357. * get both the DISP(CF_DIB) and the DISP(CF_TEXT) info in one pass, this is
  358. * much faster than doing multiple passes over the file.
  359. *
  360. ****************************************************************************/
  361. HANDLE GetRiffDisp(LPTSTR lpszFile, LPTSTR szText, int iLen)
  362. {
  363. HMMIO hmmio;
  364. MMCKINFO ck;
  365. MMCKINFO ckINFO;
  366. MMCKINFO ckRIFF;
  367. HANDLE h = NULL;
  368. LONG lSize;
  369. DWORD dw;
  370. HCURSOR hcur = NULL;
  371. if (szText)
  372. szText[0] = 0;
  373. /* 20/9/92 - reverse engineering... (Laurie Griffiths)
  374. | This routine ACTUALLY only ever gets called from PreviewFile. That's
  375. | in this file, so this routine should have been PRIVATE or STATIC.
  376. | PreviewFile is itself called from only 3 places, also all in this file.
  377. | Of these, two have NULL as the lpszFile (which is passed straight through
  378. | to here) and the other one has text derived from
  379. | SendDlgItemMessage(..., LB_GETTEXT, ...lpszFile)
  380. | So if HIWORD(lpszFile) is ever zero, it's hard to see what good it does
  381. | to take the LOWORD and cast it as an HMMIO (which would be even sillier
  382. | in 32 bit land). I reckon it will just always return.
  383. */
  384. #ifdef WIN32
  385. if (lpszFile == NULL) return NULL;
  386. hmmio = mmioOpen(lpszFile, NULL, MMIO_ALLOCBUF | MMIO_READ);
  387. #else // 16 bit idio[syncra]cy?
  388. /* Open the file */
  389. if (HIWORD(lpszFile))
  390. hmmio = mmioOpen(lpszFile, NULL, MMIO_ALLOCBUF | MMIO_READ);
  391. else
  392. hmmio = (HMMIO)LOWORD(lpszFile);
  393. #endif
  394. if (hmmio == NULL)
  395. return NULL;
  396. mmioSeek(hmmio, 0, SEEK_SET);
  397. /* descend the input file into the RIFF chunk */
  398. if (mmioDescend(hmmio, &ckRIFF, NULL, 0) != 0)
  399. goto error;
  400. if (ckRIFF.ckid != FOURCC_RIFF)
  401. goto error;
  402. while (!mmioDescend(hmmio, &ck, &ckRIFF, 0))
  403. {
  404. if (ck.ckid == FOURCC_DISP)
  405. {
  406. if (hcur == NULL)
  407. hcur = SetCursor(LoadCursor(NULL, IDC_WAIT));
  408. /* Read dword into dw, break if read unsuccessful */
  409. if (mmioRead(hmmio, (LPVOID)&dw, sizeof(dw)) != sizeof(dw))
  410. goto error;
  411. /* Find out how much memory to allocate */
  412. lSize = ck.cksize - sizeof(dw);
  413. if ((int)dw == CF_DIB && h == NULL)
  414. {
  415. /* get a handle to memory to hold the description and lock it down */
  416. if ((h = GlobalAlloc(GHND, lSize+4)) == NULL)
  417. goto error;
  418. if (mmioRead(hmmio, GlobalLock(h), lSize) != lSize)
  419. goto error;
  420. }
  421. else if ((int)dw == CF_TEXT && szText[0] == 0)
  422. {
  423. if (lSize > iLen-1)
  424. lSize = iLen-1;
  425. szText[lSize] = 0;
  426. if (mmioRead(hmmio, (LPSTR)szText, lSize) != lSize)
  427. goto error;
  428. }
  429. }
  430. else if (ck.ckid == FOURCC_LIST &&
  431. ck.fccType == FOURCC_INFO &&
  432. szText[0] == 0)
  433. {
  434. while (!mmioDescend(hmmio, &ckINFO, &ck, 0))
  435. {
  436. switch (ckINFO.ckid)
  437. {
  438. case FOURCC_INAM:
  439. // case FOURCC_ISBJ:
  440. lSize = ck.cksize;
  441. if (lSize > iLen-1)
  442. lSize = iLen-1;
  443. szText[lSize] = 0;
  444. if (mmioRead(hmmio, (LPSTR)szText, lSize) != lSize)
  445. goto error;
  446. break;
  447. }
  448. if (mmioAscend(hmmio, &ckINFO, 0))
  449. break;
  450. }
  451. }
  452. //
  453. // if we have both a picture and a title, then exit.
  454. //
  455. if (h != NULL && szText[0] != 0)
  456. break;
  457. /* Ascend so that we can descend into next chunk
  458. */
  459. if (mmioAscend(hmmio, &ck, 0))
  460. break;
  461. }
  462. goto exit;
  463. error:
  464. if (h)
  465. GlobalFree(h);
  466. h = NULL;
  467. exit:
  468. #ifdef WIN32
  469. if (hmmio != NULL)
  470. mmioClose(hmmio, 0);
  471. #else
  472. if (hmmio && HIWORD(lpszFile))
  473. mmioClose(hmmio, 0);
  474. #endif
  475. if (hcur)
  476. SetCursor(hcur);
  477. return h;
  478. }
  479. #if 0
  480. *
  481. * /***************************************************************************
  482. * *
  483. * ****************************************************************************/
  484. *
  485. * HANDLE FAR PASCAL GetRiffPicture(LPTSTR szFile)
  486. * {
  487. * return ReadDisp(szFile, CF_DIB, NULL, 0);
  488. * }
  489. *
  490. * * /***************************************************************************
  491. * * *
  492. * * ****************************************************************************/
  493. * *
  494. * * BOOL FAR PASCAL GetRiffTitle(LPSTR szFile, LPSTR szTitle, int iLen)
  495. * * {
  496. * * return ReadDisp(szFile, CF_TEXT, szTitle, iLen) ||
  497. * * ReadInfo(szFile, FOURCC_INAM, szTitle, iLen) ||
  498. * * ReadInfo(szFile, FOURCC_ISBJ, szTitle, iLen) ;
  499. * * }
  500. * /****************************************************************************
  501. * *
  502. * ****************************************************************************/
  503. *
  504. * HANDLE ReadDisp(LPSTR lpszFile, int cf, LPSTR pv, int iLen)
  505. * {
  506. * HMMIO hmmio;
  507. * MMCKINFO ckinfo;
  508. * MMCKINFO ckRIFF;
  509. * HANDLE h = NULL;
  510. * DWORD dwSize;
  511. * DWORD dw;
  512. *
  513. * if (pv)
  514. * ((LPSTR)pv)[0] = 0;
  515. *
  516. * /* Open the file */
  517. * if (HIWORD(lpszFile))
  518. * hmmio = mmioOpen(lpszFile, NULL, MMIO_ALLOCBUF | MMIO_READ);
  519. * else
  520. * hmmio = (HMMIO)LOWORD(lpszFile);
  521. *
  522. * if (hmmio == NULL)
  523. * return NULL;
  524. *
  525. * mmioSeek(hmmio, 0, SEEK_SET);
  526. *
  527. * /* descend the input file into the RIFF chunk */
  528. * if (mmioDescend(hmmio, &ckRIFF, NULL, 0) != 0)
  529. * goto error;
  530. *
  531. * if (ckRIFF.ckid != FOURCC_RIFF)
  532. * goto error;
  533. *
  534. * /* search the file for a 'DISP' chunk */
  535. * ckinfo.ckid = FOURCC_DISP;
  536. * while (!mmioDescend(hmmio, &ckinfo, &ckRIFF, MMIO_FINDCHUNK))
  537. * {
  538. * /* Read dword into dw, break if read unsuccessful */
  539. * if (mmioRead(hmmio, (LPVOID)&dw, sizeof(dw)) != sizeof(dw))
  540. * goto error;
  541. *
  542. * /* Check to see if the type is right */
  543. * if ((int)dw == cf)
  544. * {
  545. * /* Find out how much memory to allocate */
  546. * dwSize = ckinfo.cksize - sizeof(dw);
  547. *
  548. * if (pv == NULL)
  549. * {
  550. * /* get a handle to memory to hold the description and lock it down */
  551. * h = GlobalAlloc(GHND, dwSize+1);
  552. *
  553. * if (!h)
  554. * goto error;
  555. *
  556. * pv = GlobalLock(h);
  557. * }
  558. * else
  559. * {
  560. * if (dwSize > (DWORD)iLen-1)
  561. * dwSize = (DWORD)iLen-1;
  562. *
  563. * ((LPSTR)pv)[(int)dwSize] = 0;
  564. * }
  565. *
  566. * if (mmioRead(hmmio, pv, (LONG)dwSize) != (LONG)dwSize)
  567. * goto error;
  568. *
  569. * if (HIWORD(lpszFile))
  570. * mmioClose(hmmio, 0);
  571. *
  572. * return h ? h : (HANDLE)(UINT)dwSize;
  573. * }
  574. *
  575. * /* Ascend so that we can descend into next chunk
  576. * */
  577. * if(mmioAscend(hmmio, &ckinfo, 0))
  578. * break;
  579. * }
  580. *
  581. * error:
  582. * if (hmmio && HIWORD(lpszFile))
  583. * mmioClose(hmmio, 0);
  584. *
  585. * if (h)
  586. * GlobalFree(h);
  587. *
  588. * return NULL;
  589. * }
  590. *
  591. * /****************************************************************************
  592. * *
  593. * ****************************************************************************/
  594. *
  595. * HANDLE ReadInfo(LPSTR lpszFile, FOURCC fcc, LPSTR pv, int iLen)
  596. * {
  597. * HMMIO hmmio;
  598. * HANDLE h=NULL;
  599. * MMCKINFO ckinfo;
  600. * MMCKINFO ckLIST;
  601. * MMCKINFO ckRIFF;
  602. * DWORD dwSize;
  603. *
  604. * if (pv)
  605. * ((LPSTR)pv)[0] = 0;
  606. *
  607. * /* Open the file */
  608. * if (HIWORD(lpszFile))
  609. * hmmio = mmioOpen(lpszFile, NULL, MMIO_ALLOCBUF | MMIO_READ);
  610. * else
  611. * hmmio = (HMMIO)LOWORD(lpszFile);
  612. *
  613. * if (hmmio == NULL)
  614. * return NULL;
  615. *
  616. * mmioSeek(hmmio, 0, SEEK_SET);
  617. *
  618. * /* descend the input file into the RIFF chunk */
  619. * if (mmioDescend(hmmio, &ckRIFF, NULL, 0) != 0)
  620. * goto error;
  621. *
  622. * if (ckRIFF.ckid != FOURCC_RIFF)
  623. * goto error;
  624. *
  625. * ckLIST.fccType = FOURCC_INFO;
  626. * if (mmioDescend(hmmio, &ckLIST, &ckRIFF, MMIO_FINDLIST) != 0)
  627. * goto error;
  628. *
  629. * ckinfo.ckid = fcc;
  630. * if (mmioDescend(hmmio, &ckinfo, &ckLIST, MMIO_FINDCHUNK) != 0)
  631. * goto error;
  632. *
  633. * /* Find out how much memory to allocate/read */
  634. * dwSize = ckinfo.cksize;
  635. *
  636. * if (pv == NULL)
  637. * {
  638. * /* get a handle to memory to hold the description and lock it down */
  639. * h = GlobalAlloc(GHND, dwSize+1);
  640. *
  641. * if (!h)
  642. * goto error;
  643. *
  644. * pv = GlobalLock(h);
  645. * }
  646. * else
  647. * {
  648. * if (dwSize > (DWORD)iLen-1)
  649. * dwSize = (DWORD)iLen-1;
  650. *
  651. * ((LPSTR)pv)[(int)dwSize] = 0;
  652. * }
  653. *
  654. * /* read the description into the allocated memory */
  655. * if (mmioRead(hmmio, pv, (LONG)dwSize) != (LONG)dwSize)
  656. * goto error;
  657. *
  658. * if (HIWORD(lpszFile))
  659. * mmioClose(hmmio, 0);
  660. *
  661. * return h ? h : (HANDLE)(UINT)dwSize;
  662. *
  663. * error:
  664. * if (hmmio && HIWORD(lpszFile))
  665. * mmioClose(hmmio, 0);
  666. *
  667. * if (h)
  668. * GlobalFree(h);
  669. *
  670. * return NULL;
  671. * }
  672. *
  673. #endif
  674.