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.

150 lines
3.8 KiB

  1. #include <win32.h>
  2. #include "avifile.h"
  3. #include "extra.h"
  4. #include "debug.h"
  5. HRESULT ReadExtra(LPEXTRA extra,
  6. DWORD ckid,
  7. LPVOID lpData,
  8. LONG FAR *lpcbData)
  9. {
  10. #define lpdw ((DWORD FAR *) lp)
  11. LPBYTE lp = (LPBYTE) extra->lp;
  12. LONG cb = extra->cb;
  13. LONG cbData;
  14. while (cb >= 2 * sizeof(DWORD)) {
  15. cbData = (LONG) lpdw[1];
  16. if (lpdw[0] == ckid) {
  17. if (lpData) {
  18. hmemcpy(lpData, lp + 2 * sizeof(DWORD), min(cbData, *lpcbData));
  19. }
  20. *lpcbData = cbData;
  21. return ResultFromScode(AVIERR_OK);
  22. }
  23. if (cbData & 1)
  24. cbData++;
  25. cb -= cbData + sizeof(DWORD) * 2;
  26. lp += cbData + sizeof(DWORD) * 2;
  27. }
  28. #undef lpdw
  29. *lpcbData = 0;
  30. return ResultFromScode(AVIERR_NODATA);
  31. }
  32. HRESULT WriteExtra(LPEXTRA extra,
  33. DWORD ckid,
  34. LPVOID lpData,
  35. LONG cbData)
  36. {
  37. LPBYTE lp;
  38. cbData += sizeof(DWORD) * 2;
  39. if (extra->lp) {
  40. lp = (LPBYTE) GlobalReAllocPtr(extra->lp, extra->cb + cbData, GMEM_MOVEABLE | GMEM_SHARE);
  41. } else {
  42. lp = (LPBYTE) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_SHARE, cbData);
  43. }
  44. if (!lp)
  45. return ResultFromScode(AVIERR_MEMORY);
  46. // !!! Should go and get rid of other chunks with same type!
  47. // build RIFF chunk in block
  48. ((DWORD FAR *) (lp + extra->cb))[0] = ckid;
  49. ((DWORD FAR *) (lp + extra->cb))[1] = cbData - sizeof(DWORD) * 2;
  50. hmemcpy(lp + extra->cb + sizeof(DWORD) * 2,
  51. lpData,
  52. cbData - sizeof(DWORD) * 2);
  53. if (cbData & 1)
  54. cbData++;
  55. extra->lp = lp;
  56. extra->cb += cbData;
  57. return ResultFromScode(AVIERR_OK);
  58. }
  59. HRESULT ReadIntoExtra(LPEXTRA extra,
  60. HSHFILE hshfile,
  61. MMCKINFO FAR * lpck)
  62. {
  63. LPBYTE lp;
  64. LONG cbData = lpck->cksize + sizeof(DWORD) * 2;
  65. DPF("ReadIntoExtra: now %ld bytes.\n", extra->cb + cbData);
  66. if (extra->lp) {
  67. lp = (LPBYTE) GlobalReAllocPtr(extra->lp, extra->cb + cbData, GMEM_MOVEABLE | GMEM_SHARE);
  68. } else {
  69. lp = (LPBYTE) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_SHARE, cbData);
  70. }
  71. if (!lp)
  72. return ResultFromScode(AVIERR_MEMORY);
  73. extra->lp = lp;
  74. // build RIFF chunk in block
  75. ((DWORD FAR *) (lp + extra->cb))[0] = lpck->ckid;
  76. ((DWORD FAR *) (lp + extra->cb))[1] = lpck->cksize;
  77. cbData += (cbData & 1);
  78. shfileSeek(hshfile, lpck->dwDataOffset, SEEK_SET);
  79. if (shfileRead(hshfile, (HPSTR) lp + extra->cb + sizeof(DWORD) * 2, lpck->cksize) !=
  80. (LONG) lpck->cksize)
  81. return ResultFromScode(AVIERR_FILEREAD);
  82. extra->cb += cbData;
  83. return ResultFromScode(AVIERR_OK);
  84. }
  85. LONG FindChunkAndKeepExtras(LPEXTRA extra, HSHFILE hshfile,
  86. MMCKINFO FAR* lpck, MMCKINFO FAR* lpckParent,
  87. UINT uFlags)
  88. {
  89. FOURCC ckidFind; // chunk ID to find (or NULL)
  90. FOURCC fccTypeFind; // form/list type to find (or NULL)
  91. LONG lRet;
  92. /* figure out what chunk id and form/list type to search for */
  93. if (uFlags & MMIO_FINDCHUNK)
  94. ckidFind = lpck->ckid, fccTypeFind = NULL;
  95. else if (uFlags & MMIO_FINDRIFF)
  96. ckidFind = FOURCC_RIFF, fccTypeFind = lpck->fccType;
  97. else if (uFlags & MMIO_FINDLIST)
  98. ckidFind = FOURCC_LIST, fccTypeFind = lpck->fccType;
  99. else
  100. ckidFind = fccTypeFind = (FOURCC) -1; // keep looking indefinitely
  101. for (;;) {
  102. lRet = shfileDescend(hshfile, lpck, lpckParent, 0);
  103. if (lRet) {
  104. if (uFlags == 0 && lRet == MMIOERR_CHUNKNOTFOUND)
  105. lRet = 0;
  106. return lRet;
  107. }
  108. if ((!ckidFind || lpck->ckid == ckidFind) &&
  109. (!fccTypeFind || lpck->fccType == fccTypeFind))
  110. return 0;
  111. if (lpck->ckid != mmioFOURCC('J', 'U', 'N', 'K')) {
  112. lRet = (LONG) ReadIntoExtra(extra, hshfile, lpck);
  113. if (lRet != AVIERR_OK)
  114. return lRet;
  115. }
  116. shfileAscend(hshfile, lpck, 0);
  117. }
  118. }