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 >
Wrap
C/C++ Source or Header
|
1991-09-10
|
25KB
|
806 lines
/****************************************************************************
PROGRAM: MMPF.c
PURPOSE: Pull apart the MMP file format for inspection
(C) Copyright Microsoft Corp. 1991. All rights reserved.
You have a royalty-free right to use, modify, reproduce and
distribute the Sample Files (and/or any modified version) in
any way you find useful, provided that you agree that
Microsoft has no warranty obligations or liability for any
Sample Application Files which are modified.
****************************************************************************/
#include "mmpf.h"
#include "mmpfdlg.h"
#include "dlgopen.h"
HANDLE vhInst;
HANDLE ghFile = NULL;
#define MAX_LINE 7
char szLine[MAX_LINE][128];
/////////////////////////////////////////////////////////////////////////////
LONG FAR PASCAL _hread( int hFile, BYTE huge * hpBuffer, DWORD dwBytes );
DWORD FAR PASCAL ByteSwapDWORD( DWORD dw );
LPSTR FAR PASCAL lstrncpy(LPSTR dest, LPSTR source, WORD count);
WORD FAR PASCAL ByteSwapWORD( WORD w );
/////////////////////////////////////////////////////////////////////////////
DWORD FAR PASCAL ByteSwapDWORD( DWORD dw )
{
/* note if this were a macro then dw (as a function call) */
/* would be called multiple times */
return( ((dw&(0xFF000000)) >> 24) +
((dw&(0x00FF0000)) >> 8) +
((dw&(0x0000FF00)) << 8) +
((dw&(0x000000FF)) << 24) );
}
WORD FAR PASCAL ByteSwapWORD( WORD w )
{
/* note if this were a macro then w (as a function call) */
/* would be called multiple times */
return( ((w&(0xFF00)) >> 8) +
((w&(0x00FF)) << 8) );
}
/****************************************************************************
FUNCTION: WinMain
PURPOSE: Takes care of all program setup and houses the message loop
****************************************************************************/
int PASCAL WinMain(HANDLE hInst, HANDLE hPrevInst, LPSTR lpCmd, int nCmdShow)
{
MSG msg;
HWND hwnd;
FARPROC lpfnProc;
if (hPrevInst)
return FALSE;
vhInst = hInst;
lpfnProc = MakeProcInstance(MainDlgProc, vhInst);
hwnd = CreateDialog(vhInst, "MainDlg", NULL, lpfnProc);
ShowWindow(hwnd, nCmdShow);
/* Polling messages from event queue */
while ( GetMessage(&msg, NULL, 0, 0) )
{
if ( !hwnd || !IsDialogMessage(hwnd, &msg) )
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return( (int)msg.wParam );
}
DWORD tolowerCKID(DWORD ckID)
{
char *pch = (char *)&ckID;
int i;
for (i = 0; i < 4 && *pch != ' '; i++, pch++)
{
if (*pch >= 'A' && *pch <= 'Z')
*pch += ('a' - 'A');
if (*pch < 'a' || *pch > 'z')
*pch = ' ';
}
return ckID;
}
static char szRes[] = "\
cftc\
ver \
mcnm\
vwcf\
vwcr\
vwsc\
vwtc\
vwfm\
vwtl\
vwlb\
vwac\
snd \
dib \
clut\
stxt\
pict\
scvw\
str \
xxxx";
int chunkData(BYTE huge *hpFile, DWORD ckid)
{
int line = 1, i, rType = 0;
PDWORD dwRes = (PDWORD)szRes;
for (rType = 0; dwRes[rType] != *(LPDWORD)"xxxx"; rType++)
{
if (dwRes[rType] == ckid)
break;
}
switch (rType)
{
case 0: // cftc
{
WORD iCk, iDib, iClut;
DWORD dwmemSize = 0;
LPBITMAPINFOHEADER lpbi;
DWORD dwSize;
BYTE huge * hpDib, huge * hpStart;
wsprintf(szLine[line++], "Table of Contents");
hpStart = hpFile - 12;
iCk = iDib = 0;
for (dwmemSize = 0, hpFile += 0x0C; *hpFile; hpFile += 0x10)
{
iCk++;
if (*(PDWORD)"dib " == tolowerCKID(*(LPDWORD)hpFile))
{
iDib++;
hpDib = (hpStart + *(LPDWORD)(hpFile + 12));
lpbi = (LPBITMAPINFOHEADER)(hpDib += (12 + (((hpDib[12] + 2) / 2) * 2)));
// for expanded bitmap in memory
dwSize = (((lpbi->biWidth * lpbi->biBitCount) + 31) / 32) * 4;
dwmemSize += (dwSize * lpbi->biHeight);
// for the mono mask that will probably be created
dwmemSize += (((((lpbi->biWidth ) + 31) / 32) * 4) * lpbi->biHeight);
}
else
dwmemSize += *(LPDWORD)(hpFile + 4);
}
wsprintf(szLine[line++], "Chunks in file: %i", iCk);
wsprintf(szLine[line++], " Dibs in file: %i", iDib);
wsprintf(szLine[line++], "File Size >> Estimated Mem Size");
wsprintf(szLine[line++], " %ikb >> %ikb",
(WORD)(*(LPDWORD)(hpStart + 4) / 1024), (WORD)(dwmemSize / 1024));
}
break;
case 1: // ver
{
wsprintf(szLine[line++], "Convertor Version");
wsprintf(szLine[line++], "Version Number: %lX", *(LPDWORD)(hpFile + 0x8));
}
break;
case 2: // mcnm
{
wsprintf(szLine[line++], "Macintosh Movie Name");
lstrncpy(szLine[line], hpFile + 0xd, i = *(hpFile + 0xc));
szLine[line++][i] = 0;
}
break;
case 3: // vwcf
{
wsprintf(szLine[line++], "Movie Configuration");
hpFile += (12 + (((hpFile[12] + 2) / 2) * 2));
wsprintf(szLine[line++], "File Version: %x",
ByteSwapWORD(*(LPWORD)(hpFile += 0x2)));
wsprintf(szLine[line++], "Movie Rect: %i, %i, %i, %i",
ByteSwapWORD(*(LPWORD)(hpFile + 0x2)),
ByteSwapWORD(*(LPWORD)(hpFile + 0x4)),
ByteSwapWORD(*(LPWORD)(hpFile + 0x6)),
ByteSwapWORD(*(LPWORD)(hpFile + 0x8)));
wsprintf(szLine[line++], "Cast Array : %i to %i",
ByteSwapWORD(*(LPWORD)(hpFile + 0xa)),
ByteSwapWORD(*(LPWORD)(hpFile + 0xc)));
wsprintf(szLine[line++], "Initial Frame Rate: %i", *(hpFile + 0xe));
wsprintf(szLine[line++], "Bit Depth: %i",
ByteSwapWORD(*(LPWORD)(hpFile + 0x1a)));
}
break;
case 4: // vwcr
{
BYTE huge * hpEnd = hpFile + *(LPDWORD)(hpFile + 4) + 8L;
WORD wCastRecSize, i;
WORD wCast[7];
wsprintf(szLine[line++], "Cast record array");
hpFile += (12 + (((hpFile[12] + 2) / 2) * 2));
for (i = 0; i < 7; wCast[i++] = 0)
;
while (hpFile < hpEnd)
{
if (wCastRecSize = *hpFile++)
{
wCast[*hpFile]++;
hpFile += wCastRecSize;
}
}
wsprintf(szLine[line++], "Bitmap Cast Members: %i", wCast[1]);
wsprintf(szLine[line++], "Text Cast Members: %i", wCast[3]);
wsprintf(szLine[line++], "Palette Cast Members: %i", wCast[4]);
wsprintf(szLine[line++], "Sound Cast Members: %i", wCast[6]);
}
break;
case 5: // vwsc
{
WORD wFrameCount, wUpdateCount, wTapeLoc, wTapeEnd, wPal, wTrans;
WORD wFrameSize, wByteOffset, wByteCount;
DWORD dwScoreSize;
wsprintf(szLine[line++], "Movie Score");
hpFile += (12 + (((hpFile[12] + 2) / 2) * 2));
dwScoreSize = ByteSwapDWORD(*(LPDWORD)hpFile) - 4;
hpFile += 4;
wPal = wTrans = 0;
wFrameCount = wUpdateCount = 0;
while (dwScoreSize)
{
wFrameCount++;
wFrameSize = ByteSwapWORD(*(LPWORD)hpFile);
dwScoreSize -= wFrameSize;
hpFile += 2;
wTapeLoc = 0;
for (wFrameSize -= 2; wFrameSize; wFrameSize -= (wByteCount + 2))
{
wByteCount = *hpFile++ * 2;
wByteOffset = *hpFile++ * 2;
wTapeLoc += wByteOffset;
wTapeEnd = wTapeLoc + wByteCount;
if (wTapeLoc < 16)
wTrans++;
if (wTapeLoc < 32 && wTapeEnd >= 16)
wPal++;
hpFile += wByteCount;
wUpdateCount++;
}
}
wsprintf(szLine[line++], "Frames in Movie: %i", wFrameCount);
wsprintf(szLine[line++], "Frames Update Blocks: %i", wUpdateCount);
wsprintf(szLine[line++], "Update Frames - Palette: %i", wPal);
wsprintf(szLine[line++], " - Snd/Trans/Tempo/Script: %i", wTrans);
}
break;
case 6: // vwtc
{
WORD wFrames;
wsprintf(szLine[line++], "TimeCode for Frames");
hpFile += (12 + (((hpFile[12] + 2) / 2) * 2));
wFrames = ByteSwapDWORD(*(LPDWORD)hpFile);
wsprintf(szLine[line++], "Number of Frames: %i", wFrames);
wsprintf(szLine[line++], "active: %i filled: %i", hpFile[10], hpFile[11]);
hpFile += 12;
for (i = 0 ; i < wFrames / 8; i++)
wsprintf(szLine[line++], "%i, %i, %i, %i, %i, %i, %i, %i",
ByteSwapWORD(*(LPWORD)(hpFile + i * 10)),
ByteSwapWORD(*(LPWORD)(hpFile + i * 10 + 2)),
ByteSwapWORD(*(LPWORD)(hpFile + i * 10 + 4)),
ByteSwapWORD(*(LPWORD)(hpFile + i * 10 + 6)),
ByteSwapWORD(*(LPWORD)(hpFile + i * 10 + 8)),
ByteSwapWORD(*(LPWORD)(hpFile + i * 10 + 10)),
ByteSwapWORD(*(LPWORD)(hpFile + i * 10 + 12)),
ByteSwapWORD(*(LPWORD)(hpFile + i * 10 + 14)));
}
break;
case 7: // vwfm
{
BYTE huge * hpText;
WORD wFontEntries, j;
wsprintf(szLine[line++], "Font Numbers for Font Mapping");
hpFile += (12 + (((hpFile[12] + 2) / 2) * 2));
wFontEntries = ByteSwapWORD(*(LPWORD)hpFile);
hpFile += 2;
hpText = hpFile + 2 * wFontEntries;
for (i = 0; i < wFontEntries && line < MAX_LINE; i++, hpFile += 4)
{
wsprintf(szLine[line], "%4x:", ByteSwapWORD(*(LPWORD)hpFile));
lstrncpy(szLine[line] + 5, hpText + 1, j = *hpText);
szLine[line++][j + 5] = 0;
hpText += (j + 1);
}
}
break;
case 8: // vwtl
{
BYTE huge * hpEnd;
wsprintf(szLine[line++], "Pixel Pattern Tile");
hpEnd = *(LPDWORD)(hpFile + 4) + hpFile;
hpFile += (12 + (((hpFile[12] + 2) / 2) * 2));
for (i = 0; i < 8 && i < 5 && hpFile < hpEnd; i++, hpFile += 14)
{
wsprintf(szLine[line++], "cast: %i, rect:%i,%i,%i,%i",
ByteSwapWORD(*(LPWORD)(hpFile + 4)),
ByteSwapWORD(*(LPWORD)(hpFile + 6)),
ByteSwapWORD(*(LPWORD)(hpFile + 8)),
ByteSwapWORD(*(LPWORD)(hpFile + 10)),
ByteSwapWORD(*(LPWORD)(hpFile + 12)));
}
}
break;
case 9: // vwlb
{
BYTE huge * hpText;
WORD wLabelStart, wLabelEnd;
WORD wLabelEntries, j;
wsprintf(szLine[line++], "Label list");
hpFile += (12 + (((hpFile[12] + 2) / 2) * 2));
wLabelEntries = ByteSwapWORD(*(LPWORD)hpFile);
hpFile += 2;
hpText = hpFile + 4 * (wLabelEntries + 1);
for (i = 0; i < wLabelEntries && line < MAX_LINE; i++, hpFile += 4)
{
wsprintf(szLine[line], "%4i:", ByteSwapWORD(*(LPWORD)hpFile));
wLabelStart = ByteSwapWORD(*(LPWORD)(hpFile + 2));
wLabelEnd = ByteSwapWORD(*(LPWORD)(hpFile + 6));
lstrncpy(szLine[line] + 5, hpText + wLabelStart, j = (wLabelEnd - wLabelStart));
szLine[line++][j + 5] = 0;
}
}
break;
case 10: // vwac
{
BYTE huge * hpText;
WORD wActionStart, wActionEnd;
WORD wActionEntries, j;
wsprintf(szLine[line++], "Script Channel Commands");
hpFile += (12 + (((hpFile[12] + 2) / 2) * 2));
wActionEntries = ByteSwapWORD(*(LPWORD)hpFile);
hpFile += 2;
hpText = hpFile + 4 * (wActionEntries + 1);
for (i = 0; i < wActionEntries && line < MAX_LINE; i++, hpFile += 4)
{
wsprintf(szLine[line], "%2i:%2i:", *hpFile, *(hpFile + 1));
wActionStart = ByteSwapWORD(*(LPWORD)(hpFile + 2));
wActionEnd = ByteSwapWORD(*(LPWORD)(hpFile + 6));
lstrncpy(szLine[line] + 6, hpText + wActionStart, j = (wActionEnd - wActionStart));
szLine[line++][j + 6] = 0;
}
}
break;
case 11: // snd
{
hpFile += (12 + (((hpFile[12] + 2) / 2) * 2));
i = ByteSwapWORD(*(LPWORD)hpFile);
wsprintf(szLine[line++], "Format %i Sound Resource", i);
if (i == 1)
{
wsprintf(szLine[line++], "# of modifiers/synths: %i",
i = ByteSwapWORD(*(LPWORD)(hpFile + 2)));
hpFile += (i * 6 + 4);
wsprintf(szLine[line++], "# of sound commands: %i",
ByteSwapWORD(*(LPWORD)(hpFile + 4)));
}
else
{ // assuming standard data follows one command for ease
wsprintf(szLine[line++], "# of sound commands: %i",
i = ByteSwapWORD(*(LPWORD)(hpFile + 4)));
hpFile += (i * 8 + 6);
if (ByteSwapWORD(*(LPWORD)(hpFile + 4)) == 0)
{
hpFile += 4;
wsprintf(szLine[line++], "# of samples: %li",
ByteSwapDWORD(*(LPDWORD)hpFile));
wsprintf(szLine[line++], "sampling rate: %likHz",
ByteSwapDWORD(*(LPDWORD)(hpFile + 4)) / 66294000);
wsprintf(szLine[line++], "start of sampling loop: %li",
ByteSwapDWORD(*(LPDWORD)(hpFile + 8)));
wsprintf(szLine[line++], "end of sampling loop: %li",
ByteSwapDWORD(*(LPDWORD)(hpFile + 12)));
}
}
}
break;
case 12: // dib
{
LPBITMAPINFOHEADER lpbi;
DWORD dwSize;
lpbi = (LPBITMAPINFOHEADER)(hpFile += (12 + (((hpFile[12] + 2) / 2) * 2)));
wsprintf(szLine[line++], "Bitmap cast member");
wsprintf(szLine[line++], "DIB dimensions: %lix%lix%i",
lpbi->biWidth, lpbi->biHeight, lpbi->biBitCount);
wsprintf(szLine[line++], "Compression: %s",
(LPSTR)(lpbi->biCompression == BI_RGB ? "None" : "RLE"));
if (lpbi->biCompression != BI_RGB)
{
dwSize = (((lpbi->biWidth * lpbi->biBitCount) + 31) / 32) * 4;
dwSize *= lpbi->biHeight;
wsprintf(szLine[line++], " %li >> %li = %i%%",
dwSize, lpbi->biSizeImage,
(WORD)((lpbi->biSizeImage * 100) / dwSize));
}
}
break;
case 13: // clut
{
DWORD dwPalSize = (*(LPDWORD)(hpFile + 4) - (4 + (((hpFile[12] + 2) / 2) * 2))) / 6;
wsprintf(szLine[line++], "Color Lookup Table");
hpFile += (12 + (((hpFile[12] + 2) / 2) * 2));
wsprintf(szLine[line++], "Palette Entries: %li", dwPalSize);
}
break;
case 14: // stxt
{
WORD wTextLen, wScrapLen;
wsprintf(szLine[line++], "Styled Text");
hpFile += (12 + (((hpFile[12] + 2) / 2) * 2));
wsprintf(szLine[line++], "Text Format Info Len: %i",
ByteSwapDWORD(*(LPDWORD)(hpFile + 8)));
wsprintf(szLine[line++], "Text Length: %i",
i = ByteSwapDWORD(*(LPDWORD)(hpFile + 4)));
lstrncpy(szLine[line], hpFile + 12, i > 127 ? i = 127 : i);
szLine[line++][i] = 0;
}
break;
case 15: // pict
{
wsprintf(szLine[line++], "Mac Pict Record");
wsprintf(szLine[line++], "Unsupported in PC Player");
}
break;
case 16: // scvw
{
wsprintf(szLine[line++], "Director Score Cast Member");
wsprintf(szLine[line++], "Used only in authoring");
}
break;
case 17: // str
{
wsprintf(szLine[line++], "String Table");
wsprintf(szLine[line++], "(Not used in PC Player)");
hpFile += (12 + (((hpFile[12] + 2) / 2) * 2));
lstrncpy(szLine[line], hpFile + 1, i = *hpFile);
szLine[line++][i] = 0;
}
break;
case 18: // not in list
{
wsprintf(szLine[line++], "Unknown Movie Chunk");
}
break;
}
return line;
}
BOOL CurruptFile(BYTE huge *hpFile, DWORD dwfSize)
{
BYTE huge * hpStart = hpFile, huge * hpChunk;
if (dwfSize - 8 != *(LPDWORD)(hpFile + 4) &&
dwfSize != *(LPDWORD)(hpFile + 4))
return TRUE;
for (hpFile += 0x18; *hpFile; hpFile += 0x10)
{
hpChunk = hpStart + *(LPDWORD)(hpFile + 12);
if (hpChunk > hpStart + dwfSize)
return TRUE;
if (hpChunk + *(LPDWORD)(hpChunk + 4) > hpStart + dwfSize)
return TRUE;
if (*(LPDWORD)hpFile != *(LPDWORD)hpChunk)
return TRUE;
}
return FALSE;
}
/****************************************************************************
FUNCTION: MainDlgProc
PURPOSE: Message Handler for the About Dialog Box
****************************************************************************/
BOOL FAR PASCAL MainDlgProc(HWND hDlg, unsigned msg, WORD wParam, LONG lParam)
{
static char szBuf[128];
static char szckID[5] = "RIFF";
static int ndx = -1;
FARPROC lpfnProc;
int fh, i;
DWORD dwfSize;
BYTE huge * hpFile, huge * hpStart;
HWND hList;
switch (msg)
{
case WM_INITDIALOG:
EnableWindow(GetDlgItem(hDlg, IDD_MORE), FALSE);
/* Add about dialog */
AppendMenu(GetSystemMenu(hDlg, NULL), MF_STRING | MF_ENABLED, IDM_ABOUT, "About...");
return TRUE;
case WM_CLOSE:
DestroyWindow( hDlg );
return TRUE;
case WM_DESTROY:
if (ghFile)
GlobalFree(ghFile);
PostQuitMessage( 0 );
return TRUE ;
case WM_SYSCOMMAND:
switch (wParam)
{
case IDM_ABOUT:
lpfnProc = MakeProcInstance(AboutDlgProc, vhInst);
DialogBox(vhInst, "AboutDlg", hDlg, lpfnProc);
FreeProcInstance(lpfnProc);
break;
}
break;
case WM_COMMAND:
switch (wParam)
{
case IDOK:
PostMessage(hDlg, WM_CLOSE, 0, 0L);
break;
case IDD_LIST:
if (HIWORD(lParam) == LBN_SELCHANGE)
{
if (!ghFile)
break;
hList = GetDlgItem(hDlg, IDD_LIST);
ndx = SendMessage(hList, LB_GETCURSEL, 0, 0L);
for (i = 0; i < 7; i++)
*szLine[i] = 0;
hpStart = hpFile = GlobalLock(ghFile);
hpFile += (0x18 + ndx * 0x10);
*(DWORD * )szckID = tolowerCKID(*(LPDWORD)hpFile);
wsprintf(szLine[0], "id:len:pos=%s:%li:%li",
(LPSTR)szckID,
*(LPDWORD)(hpFile + 4),
*(LPDWORD)(hpFile + 12));
hpFile = (hpStart + *(LPDWORD)(hpFile + 12));
chunkData(hpFile, *(DWORD * )szckID);
for (i = 0; i < 7; i++)
SetDlgItemText(hDlg, IDD_LINE0 + i, szLine[i]);
GlobalUnlock(ghFile);
}
break;
case IDD_FILE:
fh = DlgOpenFile (
hDlg, "Open Animation File",
(LONG)OF_EXIST | OF_OPEN | OF_MUSTEXIST,
"*.mmm",
sizeof(szBuf)-1, szBuf
);
if ( fh >0 )
{
fh = _lopen(szBuf, OF_READ);
if (!fh)
{
MessageBox(hDlg, "Cannot Open filename", "Error", MB_OK);
SetWindowText(hDlg, "No File Loaded");
break;
}
if (ghFile)
{
GlobalFree(ghFile);
ghFile = NULL;
SendMessage(GetDlgItem(hDlg, IDD_LIST), LB_RESETCONTENT, 0, 0l);
}
dwfSize = _llseek(fh, 0, 2);
_llseek(fh, 0, 0);
ghFile = GlobalAlloc(GMEM_MOVEABLE | GMEM_NODISCARD, dwfSize);
hpFile = GlobalLock(ghFile);
_hread(fh, hpFile, dwfSize);
_lclose(fh);
if (CurruptFile(hpFile, dwfSize))
{
MessageBox(hDlg, "Reconvert the Movie", "Corrupt File", MB_OK);
SetWindowText(hDlg, "No File Loaded");
GlobalUnlock(ghFile);
GlobalFree(ghFile);
ghFile = NULL;
break;
}
SetWindowText(hDlg, szBuf);
hList = GetDlgItem(hDlg, IDD_LIST);
SendMessage(hList, WM_SETREDRAW, FALSE, 0l);
SendMessage(hList, LB_RESETCONTENT, 0, 0l);
for (hpFile += 0x18; *hpFile; hpFile += 0x10)
{
*(DWORD * )szckID = tolowerCKID(*(LPDWORD)hpFile);
SendMessage(hList, LB_ADDSTRING, 0, (DWORD)(LPSTR)szckID);
}
SendMessage(hList, WM_SETREDRAW, TRUE, 0l);
InvalidateRect(hList, NULL, TRUE);
UpdateWindow(hList);
SendMessage(hList, LB_SETCURSEL, 0, 0l);
SendMessage(hDlg, WM_COMMAND, IDD_LIST, MAKELONG(0, LBN_SELCHANGE));
GlobalUnlock(ghFile);
}
break;
case IDD_MORE:
if (ndx != -1)
{
// hex dump of current choice into dlg with text window
// and OK button - glorified message box
}
break;
}
}
return (FALSE);
}
/****************************************************************************
FUNCTION: AboutDlgProc
PURPOSE: Message Handler for the About Dialog Box
****************************************************************************/
BOOL FAR PASCAL AboutDlgProc(HWND hDlg, unsigned msg, WORD wParam, LONG lParam)
{
switch (msg)
{
case WM_INITDIALOG:
return (TRUE);
case WM_COMMAND:
if (wParam == IDOK || wParam == IDCANCEL)
{
EndDialog(hDlg, TRUE);
return (TRUE);
}
break;
}
return (FALSE);
}
#define READ_SIZE (1024*60L)
#define WRITE_SIZE (1024*60L)
LONG FAR PASCAL _hread( int hFile, BYTE huge * hpBuffer, DWORD dwBytes )
{
WORD nRead;
LONG lRtn;
if( !hFile || !hpBuffer )
{
return( -1 );
}
lRtn = 0;
nRead = (dwBytes > READ_SIZE) ? (WORD)READ_SIZE : (WORD)dwBytes;
nRead = _lread( hFile, (LPSTR)hpBuffer, nRead );
// dprintf( "hread read %d\n", nRead );
while( (nRead != 0) && (nRead != (WORD)(-1)) )
{
lRtn += nRead;
dwBytes -= nRead;
hpBuffer += nRead;
nRead = (dwBytes > READ_SIZE) ? (WORD)READ_SIZE : (WORD)dwBytes;
nRead = _lread( hFile, (LPSTR)hpBuffer, nRead );
// dprintf( "hread read %d\n", nRead );
}
if( nRead == (WORD)(-1) )
{
return( -1 );
}
else
{
return( lRtn );
}
}