home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-386-Vol-2of3.iso / m / mmpf.zip / MMPF.C < prev    next >
C/C++ Source or Header  |  1991-09-10  |  25KB  |  806 lines

  1. /****************************************************************************
  2.  
  3.     PROGRAM: MMPF.c
  4.  
  5.     PURPOSE: Pull apart the MMP file format for inspection
  6.  
  7.      (C) Copyright Microsoft Corp. 1991.  All rights reserved.
  8.  
  9.      You have a royalty-free right to use, modify, reproduce and 
  10.      distribute the Sample Files (and/or any modified version) in 
  11.      any way you find useful, provided that you agree that 
  12.      Microsoft has no warranty obligations or liability for any 
  13.      Sample Application Files which are modified. 
  14.  
  15. ****************************************************************************/
  16.  
  17. #include "mmpf.h"
  18. #include "mmpfdlg.h"
  19. #include "dlgopen.h"
  20.  
  21. HANDLE vhInst;
  22. HANDLE ghFile = NULL;
  23.  
  24. #define MAX_LINE 7
  25.  
  26. char    szLine[MAX_LINE][128];
  27.  
  28.  
  29. /////////////////////////////////////////////////////////////////////////////
  30.  
  31.  
  32. LONG FAR PASCAL _hread( int hFile, BYTE huge * hpBuffer, DWORD dwBytes );
  33. DWORD FAR PASCAL ByteSwapDWORD( DWORD dw );
  34. LPSTR FAR PASCAL lstrncpy(LPSTR dest, LPSTR source, WORD count);
  35. WORD FAR PASCAL ByteSwapWORD( WORD w );
  36.  
  37.  
  38. /////////////////////////////////////////////////////////////////////////////
  39.  
  40.  
  41. DWORD FAR PASCAL ByteSwapDWORD( DWORD dw )
  42. {
  43.     /* note if this were a macro then dw (as a function call) */
  44.     /* would be called multiple times */
  45.     return( ((dw&(0xFF000000)) >> 24) +
  46.             ((dw&(0x00FF0000)) >> 8) +
  47.             ((dw&(0x0000FF00)) << 8) +
  48.             ((dw&(0x000000FF)) << 24) );
  49. }
  50.  
  51.  
  52. WORD FAR PASCAL ByteSwapWORD( WORD w )
  53. {
  54.     /* note if this were a macro then w (as a function call) */
  55.     /* would be called multiple times */
  56.     return( ((w&(0xFF00)) >> 8) +
  57.             ((w&(0x00FF)) << 8) );
  58. }
  59.  
  60.  
  61.  
  62. /****************************************************************************
  63.  
  64.     FUNCTION: WinMain
  65.  
  66.     PURPOSE:  Takes care of all program setup and houses the message loop
  67.  
  68. ****************************************************************************/
  69.  
  70. int    PASCAL WinMain(HANDLE hInst, HANDLE hPrevInst, LPSTR lpCmd, int nCmdShow)
  71. {
  72.     MSG msg;
  73.     HWND    hwnd;
  74.     FARPROC lpfnProc;
  75.  
  76.     if (hPrevInst)
  77.         return FALSE;
  78.     vhInst = hInst;
  79.  
  80.     lpfnProc = MakeProcInstance(MainDlgProc, vhInst);
  81.     hwnd = CreateDialog(vhInst, "MainDlg", NULL, lpfnProc);
  82.  
  83.     ShowWindow(hwnd, nCmdShow);
  84.  
  85. /* Polling messages from event queue */
  86.  
  87.     while ( GetMessage(&msg, NULL, 0, 0) )
  88.     {
  89.         if ( !hwnd || !IsDialogMessage(hwnd, &msg) )
  90.         {
  91.             TranslateMessage(&msg);
  92.             DispatchMessage(&msg);
  93.         }
  94.     }
  95.     return( (int)msg.wParam );
  96. }
  97.  
  98.  
  99. DWORD tolowerCKID(DWORD ckID)
  100. {
  101.     char    *pch = (char *)&ckID;
  102.     int    i;
  103.  
  104.     for (i = 0; i < 4 && *pch != ' '; i++, pch++) 
  105.     {
  106.         if (*pch >= 'A' && *pch <= 'Z')
  107.             *pch += ('a' - 'A');
  108.         if (*pch < 'a' || *pch > 'z')
  109.             *pch = ' ';
  110.     }
  111.     return ckID;
  112. }
  113.  
  114.  
  115. static char    szRes[] = "\
  116. cftc\
  117. ver \
  118. mcnm\
  119. vwcf\
  120. vwcr\
  121. vwsc\
  122. vwtc\
  123. vwfm\
  124. vwtl\
  125. vwlb\
  126. vwac\
  127. snd \
  128. dib \
  129. clut\
  130. stxt\
  131. pict\
  132. scvw\
  133. str \
  134. xxxx";
  135.  
  136. int    chunkData(BYTE huge *hpFile, DWORD ckid)
  137. {
  138.     int    line = 1, i, rType = 0;
  139.     PDWORD dwRes = (PDWORD)szRes;
  140.  
  141.  
  142.     for (rType = 0; dwRes[rType] != *(LPDWORD)"xxxx"; rType++) 
  143.     {
  144.         if (dwRes[rType] == ckid)
  145.             break;
  146.     }
  147.  
  148.     switch (rType) 
  149.     {
  150.     case 0:  // cftc
  151.  
  152.         {
  153.             WORD    iCk, iDib, iClut;
  154.             DWORD   dwmemSize = 0;
  155.             LPBITMAPINFOHEADER lpbi;
  156.             DWORD   dwSize;
  157.             BYTE    huge * hpDib, huge * hpStart;
  158.  
  159.             wsprintf(szLine[line++], "Table of Contents");
  160.             hpStart = hpFile - 12;
  161.             iCk = iDib = 0;
  162.             for (dwmemSize = 0, hpFile += 0x0C; *hpFile; hpFile += 0x10) 
  163.             {
  164.                 iCk++;
  165.  
  166.                 if (*(PDWORD)"dib " == tolowerCKID(*(LPDWORD)hpFile)) 
  167.                 {
  168.                     iDib++;
  169.                     hpDib = (hpStart + *(LPDWORD)(hpFile + 12));
  170.  
  171.                     lpbi = (LPBITMAPINFOHEADER)(hpDib += (12 + (((hpDib[12] + 2) / 2) * 2)));
  172.  
  173. // for expanded bitmap in memory
  174.                                     dwSize = (((lpbi->biWidth * lpbi->biBitCount) + 31) / 32) * 4;
  175.                     dwmemSize += (dwSize * lpbi->biHeight);
  176.  
  177. // for the mono mask that will probably be created
  178.                                     dwmemSize += (((((lpbi->biWidth ) + 31) / 32) * 4) * lpbi->biHeight);
  179.                 }
  180.                 else
  181.                     dwmemSize += *(LPDWORD)(hpFile + 4);
  182.             }
  183.  
  184.             wsprintf(szLine[line++], "Chunks in file: %i", iCk);
  185.             wsprintf(szLine[line++], "  Dibs in file: %i", iDib);
  186.             wsprintf(szLine[line++], "File Size >> Estimated Mem Size");
  187.             wsprintf(szLine[line++], "  %ikb >> %ikb",
  188.                 (WORD)(*(LPDWORD)(hpStart + 4) / 1024), (WORD)(dwmemSize / 1024));
  189.         }
  190.         break;
  191.  
  192.     case 1:  // ver
  193.  
  194.         {
  195.             wsprintf(szLine[line++], "Convertor Version");
  196.             wsprintf(szLine[line++], "Version Number: %lX", *(LPDWORD)(hpFile + 0x8));
  197.         }
  198.         break;
  199.  
  200.     case 2:  // mcnm
  201.  
  202.         {
  203.             wsprintf(szLine[line++], "Macintosh Movie Name");
  204.             lstrncpy(szLine[line], hpFile + 0xd, i = *(hpFile + 0xc));
  205.             szLine[line++][i] = 0;
  206.         }
  207.         break;
  208.  
  209.     case 3:  // vwcf
  210.  
  211.         {
  212.             wsprintf(szLine[line++], "Movie Configuration");
  213.  
  214.             hpFile += (12 + (((hpFile[12] + 2) / 2) * 2));
  215.  
  216.             wsprintf(szLine[line++], "File Version: %x",
  217.                 ByteSwapWORD(*(LPWORD)(hpFile += 0x2)));
  218.             wsprintf(szLine[line++], "Movie Rect: %i, %i, %i, %i",
  219.                 ByteSwapWORD(*(LPWORD)(hpFile + 0x2)),
  220.                 ByteSwapWORD(*(LPWORD)(hpFile + 0x4)),
  221.                 ByteSwapWORD(*(LPWORD)(hpFile + 0x6)),
  222.                 ByteSwapWORD(*(LPWORD)(hpFile + 0x8)));
  223.             wsprintf(szLine[line++], "Cast Array : %i to %i",
  224.                 ByteSwapWORD(*(LPWORD)(hpFile + 0xa)),
  225.                 ByteSwapWORD(*(LPWORD)(hpFile + 0xc)));
  226.             wsprintf(szLine[line++], "Initial Frame Rate: %i", *(hpFile + 0xe));
  227.             wsprintf(szLine[line++], "Bit Depth: %i",
  228.                 ByteSwapWORD(*(LPWORD)(hpFile + 0x1a)));
  229.         }
  230.         break;
  231.  
  232.     case 4:  // vwcr
  233.  
  234.         {
  235.             BYTE huge * hpEnd = hpFile + *(LPDWORD)(hpFile + 4) + 8L;
  236.             WORD wCastRecSize, i;
  237.             WORD wCast[7];
  238.  
  239.             wsprintf(szLine[line++], "Cast record array");
  240.             hpFile += (12 + (((hpFile[12] + 2) / 2) * 2));
  241.  
  242.             for (i = 0; i < 7; wCast[i++] = 0)
  243.                 ;
  244.             while (hpFile < hpEnd) 
  245.             {
  246.                 if (wCastRecSize = *hpFile++) 
  247.                 {
  248.                     wCast[*hpFile]++;
  249.                     hpFile += wCastRecSize;
  250.                 }
  251.             }
  252.             wsprintf(szLine[line++], "Bitmap Cast Members:  %i", wCast[1]);
  253.             wsprintf(szLine[line++], "Text Cast Members:    %i", wCast[3]);
  254.             wsprintf(szLine[line++], "Palette Cast Members: %i", wCast[4]);
  255.             wsprintf(szLine[line++], "Sound Cast Members:   %i", wCast[6]);
  256.         }
  257.         break;
  258.  
  259.     case 5:  // vwsc
  260.  
  261.         {
  262.             WORD    wFrameCount, wUpdateCount, wTapeLoc, wTapeEnd, wPal, wTrans;
  263.             WORD    wFrameSize, wByteOffset, wByteCount;
  264.             DWORD   dwScoreSize;
  265.  
  266.             wsprintf(szLine[line++], "Movie Score");
  267.             hpFile += (12 + (((hpFile[12] + 2) / 2) * 2));
  268.  
  269.             dwScoreSize = ByteSwapDWORD(*(LPDWORD)hpFile) - 4;
  270.             hpFile += 4;
  271.             wPal = wTrans = 0;
  272.             wFrameCount = wUpdateCount = 0;
  273.             while (dwScoreSize) 
  274.             {
  275.                 wFrameCount++;
  276.                 wFrameSize = ByteSwapWORD(*(LPWORD)hpFile);
  277.                 dwScoreSize -= wFrameSize;
  278.                 hpFile += 2;
  279.                 wTapeLoc = 0;
  280.  
  281.                 for (wFrameSize -= 2; wFrameSize; wFrameSize -= (wByteCount + 2)) 
  282.                 {
  283.                     wByteCount =  *hpFile++ * 2;
  284.                     wByteOffset = *hpFile++ * 2;
  285.  
  286.                     wTapeLoc += wByteOffset;
  287.                     wTapeEnd = wTapeLoc + wByteCount;
  288.                     if (wTapeLoc < 16)
  289.                         wTrans++;
  290.                     if (wTapeLoc < 32 && wTapeEnd >= 16)
  291.                         wPal++;
  292.  
  293.                     hpFile += wByteCount;
  294.                     wUpdateCount++;
  295.                 }
  296.             }
  297.             wsprintf(szLine[line++], "Frames in Movie: %i", wFrameCount);
  298.             wsprintf(szLine[line++], "Frames Update Blocks: %i", wUpdateCount);
  299.             wsprintf(szLine[line++], "Update Frames - Palette: %i", wPal);
  300.             wsprintf(szLine[line++], " - Snd/Trans/Tempo/Script: %i", wTrans);
  301.         }
  302.         break;
  303.  
  304.     case 6:  // vwtc
  305.  
  306.         {
  307.             WORD    wFrames;
  308.  
  309.             wsprintf(szLine[line++], "TimeCode for Frames");
  310.             hpFile += (12 + (((hpFile[12] + 2) / 2) * 2));
  311.  
  312.             wFrames = ByteSwapDWORD(*(LPDWORD)hpFile);
  313.             wsprintf(szLine[line++], "Number of Frames: %i", wFrames);
  314.             wsprintf(szLine[line++], "active: %i  filled: %i", hpFile[10], hpFile[11]);
  315.             hpFile += 12;
  316.             for (i = 0 ; i < wFrames / 8; i++)
  317.                 wsprintf(szLine[line++], "%i, %i, %i, %i, %i, %i, %i, %i",
  318.                     ByteSwapWORD(*(LPWORD)(hpFile + i * 10)),
  319.                     ByteSwapWORD(*(LPWORD)(hpFile + i * 10 + 2)),
  320.                     ByteSwapWORD(*(LPWORD)(hpFile + i * 10 + 4)),
  321.                     ByteSwapWORD(*(LPWORD)(hpFile + i * 10 + 6)),
  322.                     ByteSwapWORD(*(LPWORD)(hpFile + i * 10 + 8)),
  323.                     ByteSwapWORD(*(LPWORD)(hpFile + i * 10 + 10)),
  324.                     ByteSwapWORD(*(LPWORD)(hpFile + i * 10 + 12)),
  325.                     ByteSwapWORD(*(LPWORD)(hpFile + i * 10 + 14)));
  326.         }
  327.         break;
  328.  
  329.     case 7:  // vwfm
  330.  
  331.         {
  332.             BYTE    huge * hpText;
  333.             WORD    wFontEntries, j;
  334.  
  335.             wsprintf(szLine[line++], "Font Numbers for Font Mapping");
  336.             hpFile += (12 + (((hpFile[12] + 2) / 2) * 2));
  337.  
  338.             wFontEntries = ByteSwapWORD(*(LPWORD)hpFile);
  339.             hpFile += 2;
  340.             hpText = hpFile + 2 * wFontEntries;
  341.  
  342.             for (i = 0; i < wFontEntries && line < MAX_LINE; i++, hpFile += 4) 
  343.             {
  344.                 wsprintf(szLine[line], "%4x:", ByteSwapWORD(*(LPWORD)hpFile));
  345.  
  346.                 lstrncpy(szLine[line] + 5, hpText + 1, j = *hpText);
  347.                 szLine[line++][j + 5] = 0;
  348.                 hpText += (j + 1);
  349.             }
  350.         }
  351.         break;
  352.  
  353.     case 8:  // vwtl
  354.  
  355.         {
  356.             BYTE huge * hpEnd;
  357.  
  358.             wsprintf(szLine[line++], "Pixel Pattern Tile");
  359.             hpEnd = *(LPDWORD)(hpFile + 4) + hpFile;
  360.             hpFile += (12 + (((hpFile[12] + 2) / 2) * 2));
  361.  
  362.             for (i = 0; i < 8 && i < 5 && hpFile < hpEnd; i++, hpFile += 14) 
  363.             {
  364.                 wsprintf(szLine[line++], "cast: %i, rect:%i,%i,%i,%i",
  365.                     ByteSwapWORD(*(LPWORD)(hpFile + 4)),
  366.                     ByteSwapWORD(*(LPWORD)(hpFile + 6)),
  367.                     ByteSwapWORD(*(LPWORD)(hpFile + 8)),
  368.                     ByteSwapWORD(*(LPWORD)(hpFile + 10)),
  369.                     ByteSwapWORD(*(LPWORD)(hpFile + 12)));
  370.             }
  371.  
  372.         }
  373.         break;
  374.  
  375.     case 9:  // vwlb
  376.  
  377.         {
  378.             BYTE    huge * hpText;
  379.             WORD    wLabelStart, wLabelEnd;
  380.             WORD    wLabelEntries, j;
  381.  
  382.             wsprintf(szLine[line++], "Label list");
  383.             hpFile += (12 + (((hpFile[12] + 2) / 2) * 2));
  384.  
  385.             wLabelEntries = ByteSwapWORD(*(LPWORD)hpFile);
  386.             hpFile += 2;
  387.             hpText = hpFile + 4 * (wLabelEntries + 1);
  388.  
  389.             for (i = 0; i < wLabelEntries && line < MAX_LINE; i++, hpFile += 4) 
  390.             {
  391.                 wsprintf(szLine[line], "%4i:", ByteSwapWORD(*(LPWORD)hpFile));
  392.  
  393.                 wLabelStart = ByteSwapWORD(*(LPWORD)(hpFile + 2));
  394.                 wLabelEnd = ByteSwapWORD(*(LPWORD)(hpFile + 6));
  395.                 lstrncpy(szLine[line] + 5, hpText + wLabelStart, j = (wLabelEnd - wLabelStart));
  396.                 szLine[line++][j + 5] = 0;
  397.             }
  398.         }
  399.         break;
  400.  
  401.     case 10:  // vwac
  402.  
  403.         {
  404.             BYTE    huge * hpText;
  405.             WORD    wActionStart, wActionEnd;
  406.             WORD    wActionEntries, j;
  407.  
  408.             wsprintf(szLine[line++], "Script Channel Commands");
  409.             hpFile += (12 + (((hpFile[12] + 2) / 2) * 2));
  410.  
  411.             wActionEntries = ByteSwapWORD(*(LPWORD)hpFile);
  412.             hpFile += 2;
  413.             hpText = hpFile + 4 * (wActionEntries + 1);
  414.  
  415.             for (i = 0; i < wActionEntries && line < MAX_LINE; i++, hpFile += 4) 
  416.             {
  417.                 wsprintf(szLine[line], "%2i:%2i:", *hpFile, *(hpFile + 1));
  418.  
  419.                 wActionStart = ByteSwapWORD(*(LPWORD)(hpFile + 2));
  420.                 wActionEnd = ByteSwapWORD(*(LPWORD)(hpFile + 6));
  421.                 lstrncpy(szLine[line] + 6, hpText + wActionStart, j = (wActionEnd - wActionStart));
  422.                 szLine[line++][j + 6] = 0;
  423.             }
  424.         }
  425.         break;
  426.  
  427.     case 11:  // snd 
  428.  
  429.         {
  430.             hpFile += (12 + (((hpFile[12] + 2) / 2) * 2));
  431.  
  432.             i = ByteSwapWORD(*(LPWORD)hpFile);
  433.             wsprintf(szLine[line++], "Format %i Sound Resource", i);
  434.             if (i == 1) 
  435.             {
  436.                 wsprintf(szLine[line++], "# of modifiers/synths: %i",
  437.                     i = ByteSwapWORD(*(LPWORD)(hpFile + 2)));
  438.                 hpFile += (i * 6 + 4);
  439.                 wsprintf(szLine[line++], "# of sound commands: %i",
  440.                     ByteSwapWORD(*(LPWORD)(hpFile + 4)));
  441.             }
  442.             else 
  443. {      // assuming standard data follows one command for ease
  444.  
  445.                 wsprintf(szLine[line++], "# of sound commands: %i",
  446.                     i = ByteSwapWORD(*(LPWORD)(hpFile + 4)));
  447.                 hpFile += (i * 8 + 6);
  448.                 if (ByteSwapWORD(*(LPWORD)(hpFile + 4)) == 0) 
  449.                 {
  450.                     hpFile += 4;
  451.                     wsprintf(szLine[line++], "# of samples: %li",
  452.                         ByteSwapDWORD(*(LPDWORD)hpFile));
  453.                     wsprintf(szLine[line++], "sampling rate: %likHz",
  454.                         ByteSwapDWORD(*(LPDWORD)(hpFile + 4)) / 66294000);
  455.                     wsprintf(szLine[line++], "start of sampling loop: %li",
  456.                         ByteSwapDWORD(*(LPDWORD)(hpFile + 8)));
  457.                     wsprintf(szLine[line++], "end of sampling loop: %li",
  458.                         ByteSwapDWORD(*(LPDWORD)(hpFile + 12)));
  459.                 }
  460.             }
  461.         }
  462.         break;
  463.  
  464.     case 12:  // dib 
  465.  
  466.         {
  467.             LPBITMAPINFOHEADER lpbi;
  468.             DWORD   dwSize;
  469.  
  470.             lpbi = (LPBITMAPINFOHEADER)(hpFile += (12 + (((hpFile[12] + 2) / 2) * 2)));
  471.  
  472.             wsprintf(szLine[line++], "Bitmap cast member");
  473.             wsprintf(szLine[line++], "DIB dimensions: %lix%lix%i",
  474.                 lpbi->biWidth, lpbi->biHeight, lpbi->biBitCount);
  475.             wsprintf(szLine[line++], "Compression: %s",
  476.                 (LPSTR)(lpbi->biCompression == BI_RGB ? "None" : "RLE"));
  477.             if (lpbi->biCompression != BI_RGB) 
  478.             {
  479.                 dwSize = (((lpbi->biWidth * lpbi->biBitCount) + 31) / 32) * 4;
  480.                 dwSize *= lpbi->biHeight;
  481.  
  482.                 wsprintf(szLine[line++], " %li >> %li = %i%%",
  483.                     dwSize, lpbi->biSizeImage,
  484.                     (WORD)((lpbi->biSizeImage * 100) / dwSize));
  485.             }
  486.         }
  487.         break;
  488.  
  489.     case 13:  // clut
  490.  
  491.         {
  492.             DWORD dwPalSize = (*(LPDWORD)(hpFile + 4) - (4 + (((hpFile[12] + 2) / 2) * 2))) / 6;
  493.  
  494.             wsprintf(szLine[line++], "Color Lookup Table");
  495.             hpFile += (12 + (((hpFile[12] + 2) / 2) * 2));
  496.  
  497.             wsprintf(szLine[line++], "Palette Entries: %li", dwPalSize);
  498.         }
  499.         break;
  500.  
  501.     case 14:  // stxt
  502.  
  503.         {
  504.             WORD    wTextLen, wScrapLen;
  505.             wsprintf(szLine[line++], "Styled Text");
  506.             hpFile += (12 + (((hpFile[12] + 2) / 2) * 2));
  507.  
  508.             wsprintf(szLine[line++], "Text Format Info Len: %i",
  509.                 ByteSwapDWORD(*(LPDWORD)(hpFile + 8)));
  510.             wsprintf(szLine[line++], "Text Length: %i",
  511.                 i = ByteSwapDWORD(*(LPDWORD)(hpFile + 4)));
  512.             lstrncpy(szLine[line], hpFile + 12, i > 127 ? i = 127 : i);
  513.             szLine[line++][i] = 0;
  514.         }
  515.         break;
  516.  
  517.     case 15:  // pict
  518.  
  519.         {
  520.             wsprintf(szLine[line++], "Mac Pict Record");
  521.             wsprintf(szLine[line++], "Unsupported in PC Player");
  522.         }
  523.         break;
  524.  
  525.     case 16:  // scvw
  526.  
  527.         {
  528.             wsprintf(szLine[line++], "Director Score Cast Member");
  529.             wsprintf(szLine[line++], "Used only in authoring");
  530.         }
  531.         break;
  532.  
  533.     case 17:  // str
  534.  
  535.         {
  536.             wsprintf(szLine[line++], "String Table");
  537.             wsprintf(szLine[line++], "(Not used in PC Player)");
  538.             hpFile += (12 + (((hpFile[12] + 2) / 2) * 2));
  539.             lstrncpy(szLine[line], hpFile + 1, i = *hpFile);
  540.             szLine[line++][i] = 0;
  541.         }
  542.         break;
  543.  
  544.     case 18:  // not in list
  545.  
  546.         {
  547.             wsprintf(szLine[line++], "Unknown Movie Chunk");
  548.         }
  549.         break;
  550.  
  551.     }
  552.     return line;
  553. }
  554.  
  555.  
  556. BOOL CurruptFile(BYTE huge *hpFile, DWORD dwfSize)
  557. {
  558.     BYTE huge * hpStart = hpFile, huge * hpChunk;
  559.  
  560.     if (dwfSize - 8 != *(LPDWORD)(hpFile + 4) && 
  561.         dwfSize != *(LPDWORD)(hpFile + 4))
  562.         return TRUE;
  563.  
  564.     for (hpFile += 0x18; *hpFile; hpFile += 0x10) 
  565.     {
  566.         hpChunk = hpStart + *(LPDWORD)(hpFile + 12);
  567.         if (hpChunk > hpStart + dwfSize)
  568.             return TRUE;
  569.         if (hpChunk + *(LPDWORD)(hpChunk + 4) > hpStart + dwfSize)
  570.             return TRUE;
  571.         if (*(LPDWORD)hpFile != *(LPDWORD)hpChunk)
  572.             return TRUE;
  573.     }
  574.  
  575.     return FALSE;
  576. }
  577.  
  578.  
  579. /****************************************************************************
  580.  
  581.     FUNCTION: MainDlgProc
  582.  
  583.     PURPOSE:  Message Handler for the About Dialog Box
  584.  
  585. ****************************************************************************/
  586.  
  587. BOOL FAR PASCAL MainDlgProc(HWND hDlg, unsigned msg, WORD wParam, LONG lParam)
  588. {
  589.     static char    szBuf[128];
  590.     static char    szckID[5] = "RIFF";
  591.     static int    ndx = -1;
  592.  
  593.     FARPROC lpfnProc;
  594.     int    fh, i;
  595.     DWORD        dwfSize;
  596.     BYTE        huge * hpFile, huge * hpStart;
  597.     HWND        hList;
  598.  
  599.     switch (msg) 
  600.     {
  601.     case WM_INITDIALOG:
  602.         EnableWindow(GetDlgItem(hDlg, IDD_MORE), FALSE);
  603. /* Add about dialog */
  604.         AppendMenu(GetSystemMenu(hDlg, NULL), MF_STRING | MF_ENABLED, IDM_ABOUT, "About...");
  605.         return TRUE;
  606.  
  607.     case WM_CLOSE:
  608.         DestroyWindow( hDlg );
  609.         return TRUE;
  610.  
  611.     case WM_DESTROY:
  612.         if (ghFile)
  613.             GlobalFree(ghFile);
  614.         PostQuitMessage( 0 );
  615.         return TRUE ;
  616.  
  617.     case WM_SYSCOMMAND:
  618.         switch (wParam) 
  619.         {
  620.         case IDM_ABOUT:
  621.             lpfnProc = MakeProcInstance(AboutDlgProc, vhInst);
  622.             DialogBox(vhInst, "AboutDlg", hDlg, lpfnProc);
  623.             FreeProcInstance(lpfnProc);
  624.             break;
  625.         }
  626.         break;
  627.  
  628.     case WM_COMMAND:
  629.         switch (wParam) 
  630.         {
  631.         case IDOK:
  632.             PostMessage(hDlg, WM_CLOSE, 0, 0L);
  633.             break;
  634.  
  635.         case IDD_LIST:
  636.             if (HIWORD(lParam) == LBN_SELCHANGE)
  637.             {
  638.                 if (!ghFile)
  639.                     break;
  640.                 hList = GetDlgItem(hDlg, IDD_LIST);
  641.                 ndx = SendMessage(hList, LB_GETCURSEL, 0, 0L);
  642.  
  643.                 for (i = 0; i < 7; i++)
  644.                     *szLine[i] = 0;
  645.  
  646.                 hpStart = hpFile = GlobalLock(ghFile);
  647.                 hpFile += (0x18 + ndx * 0x10);
  648.  
  649.                 *(DWORD * )szckID = tolowerCKID(*(LPDWORD)hpFile);
  650.                 wsprintf(szLine[0], "id:len:pos=%s:%li:%li",
  651.                     (LPSTR)szckID,
  652.                     *(LPDWORD)(hpFile + 4),
  653.                     *(LPDWORD)(hpFile + 12));
  654.  
  655.                 hpFile = (hpStart + *(LPDWORD)(hpFile + 12));
  656.                 chunkData(hpFile, *(DWORD * )szckID);
  657.  
  658.                 for (i = 0; i < 7; i++)
  659.                     SetDlgItemText(hDlg, IDD_LINE0 + i, szLine[i]);
  660.  
  661.                 GlobalUnlock(ghFile);
  662.             }
  663.             break;
  664.  
  665.         case IDD_FILE:
  666.         fh = DlgOpenFile (
  667.                 hDlg, "Open Animation File",
  668.                (LONG)OF_EXIST | OF_OPEN | OF_MUSTEXIST,
  669.                "*.mmm",
  670.                sizeof(szBuf)-1, szBuf
  671.              );
  672.             if ( fh >0 )
  673.             {
  674.                 fh = _lopen(szBuf, OF_READ);
  675.                 if (!fh) 
  676.                 {
  677.                     MessageBox(hDlg, "Cannot Open filename", "Error", MB_OK);
  678.                     SetWindowText(hDlg, "No File Loaded");
  679.                     break;
  680.                 }
  681.                 if (ghFile) 
  682.                 {
  683.                     GlobalFree(ghFile);
  684.                     ghFile = NULL;
  685.                     SendMessage(GetDlgItem(hDlg, IDD_LIST), LB_RESETCONTENT, 0, 0l);
  686.                 }
  687.                 dwfSize = _llseek(fh, 0, 2);
  688.                 _llseek(fh, 0, 0);
  689.                 ghFile = GlobalAlloc(GMEM_MOVEABLE | GMEM_NODISCARD, dwfSize);
  690.                 hpFile = GlobalLock(ghFile);
  691.                 _hread(fh, hpFile, dwfSize);
  692.                 _lclose(fh);
  693.  
  694.                 if (CurruptFile(hpFile, dwfSize)) 
  695.                 {
  696.                     MessageBox(hDlg, "Reconvert the Movie", "Corrupt File", MB_OK);
  697.                     SetWindowText(hDlg, "No File Loaded");
  698.                     GlobalUnlock(ghFile);
  699.                     GlobalFree(ghFile);
  700.                     ghFile = NULL;
  701.                     break;
  702.                 }
  703.  
  704.                 SetWindowText(hDlg, szBuf);
  705.  
  706.                 hList = GetDlgItem(hDlg, IDD_LIST);
  707.                 SendMessage(hList, WM_SETREDRAW, FALSE, 0l);
  708.                 SendMessage(hList, LB_RESETCONTENT, 0, 0l);
  709.  
  710.                 for (hpFile += 0x18; *hpFile; hpFile += 0x10) 
  711.                 {
  712.                     *(DWORD * )szckID = tolowerCKID(*(LPDWORD)hpFile);
  713.                     SendMessage(hList, LB_ADDSTRING, 0, (DWORD)(LPSTR)szckID);
  714.                 }
  715.  
  716.                 SendMessage(hList, WM_SETREDRAW, TRUE, 0l);
  717.  
  718.                 InvalidateRect(hList, NULL, TRUE);
  719.                 UpdateWindow(hList);
  720.                 SendMessage(hList, LB_SETCURSEL, 0, 0l);
  721.                 SendMessage(hDlg, WM_COMMAND, IDD_LIST, MAKELONG(0, LBN_SELCHANGE));
  722.  
  723.                 GlobalUnlock(ghFile);
  724.             }
  725.             break;
  726.  
  727.         case IDD_MORE:
  728.             if (ndx != -1) 
  729.             {
  730. //                hex dump of current choice into dlg with text window
  731. //                  and OK button - glorified message box
  732.             }
  733.             break;
  734.         }
  735.     }
  736.     return (FALSE);
  737. }
  738.  
  739.  
  740. /****************************************************************************
  741.  
  742.     FUNCTION: AboutDlgProc
  743.  
  744.     PURPOSE:  Message Handler for the About Dialog Box
  745.  
  746. ****************************************************************************/
  747.  
  748. BOOL FAR PASCAL AboutDlgProc(HWND hDlg, unsigned msg, WORD wParam, LONG lParam)
  749. {
  750.     switch (msg) 
  751.     {
  752.     case WM_INITDIALOG:
  753.         return (TRUE);
  754.  
  755.     case WM_COMMAND:
  756.         if (wParam == IDOK || wParam == IDCANCEL) 
  757.         {
  758.             EndDialog(hDlg, TRUE);
  759.             return (TRUE);
  760.         }
  761.         break;
  762.     }
  763.     return (FALSE);
  764. }
  765.  
  766.  
  767.  
  768. #define READ_SIZE (1024*60L)
  769. #define WRITE_SIZE (1024*60L)
  770.  
  771.  
  772. LONG FAR PASCAL _hread( int hFile, BYTE huge * hpBuffer, DWORD dwBytes ) 
  773. {
  774.     WORD nRead;
  775.     LONG lRtn;
  776.  
  777.     
  778.     if( !hFile || !hpBuffer ) 
  779.     {
  780.     return( -1 );
  781.     }
  782.     
  783.     lRtn = 0;
  784.     nRead = (dwBytes > READ_SIZE) ? (WORD)READ_SIZE : (WORD)dwBytes;
  785.     nRead = _lread( hFile, (LPSTR)hpBuffer, nRead );
  786. //    dprintf( "hread read %d\n", nRead );
  787.     while( (nRead != 0) && (nRead != (WORD)(-1)) ) 
  788.     {
  789.     lRtn += nRead;
  790.     dwBytes -= nRead;
  791.     hpBuffer += nRead;
  792.         nRead = (dwBytes > READ_SIZE) ? (WORD)READ_SIZE : (WORD)dwBytes;
  793.         nRead = _lread( hFile, (LPSTR)hpBuffer, nRead );
  794. //        dprintf( "hread read %d\n", nRead );
  795.     }
  796.     if( nRead == (WORD)(-1) ) 
  797.     {
  798.     return( -1 );
  799.     }
  800.     else 
  801.     {
  802.     return( lRtn );
  803.     }
  804. }
  805.  
  806.