📄 vmcrc32.cpp
字号:
/*****************************************************************************/
/* SOURCE FILE */
/*****************************************************************************/
/*
$Archive: $
$Revision: $
Last Checkin:
$Date: $
By:
$Author: $
Last Modification:
$ModTime: $
Description: This file is part of a project downloaded from the web.
It has been reformatted and significantly cleaned up so
may not resemble the original file very much at all. The
original authors comments follow:
VMCrc32.cpp : implementation file for the VMCrc32 class
written by PJ Arends
pja@telus.net
based on the CRC-32 code found at
http://www.createwindow.com/programming/crc32/crcfile.htm
For updates check http://www3.telus.net/pja/crc32.htm
This code is provided as is, with no warranty as to it's
suitability or usefulness in any application in which it
may be used. This code has not been tested for UNICODE
builds, nor has it been tested on a network (with UNC paths).
This code may be used in any way you desire. This file may be
redistributed by any means as long as it is not sold for
profit, and providing that this notice and the authors name
are included.
If any bugs are found and fixed, a note to the author explaining
the problem and fix would be nice.
created : October 2001
Revision History:
October 11, 2001 - changed SendMessage to PostMessage
in CRC32ThreadProc
*/
static char OBJECT_ID[] = "$Revision: $ : $JustDate: $";
/*****************************************************************************/
#include "VMCRC32.h"
#include <io.h>
#include <fcntl.h>
#include <share.h>
#include <tchar.h>
#include <commctrl.h>
// use a 100 KB buffer (a larger buffer does not seem to run significantly faster,
// but takes more RAM)
//
#define BUFFERSIZE 102400
/*****************************************************************************/
/*
FUNCTION NAME: VMCrc32::CRC32ThreadProc
DESCRIPTION: If this function is started as a thread, it will send
PBM_* messages to the supplied progress bar control. When
the thread is finished, this function will send a message
of type "WM_CRC_THREAD_DONE" to the parent window of the
progress bar. the WPARAM parameter will contain the HANDLE
of the thread, and the LPARAM will contain the CRC-32 value
of the supplied buffer or file.
INPUT: lpVoid - A pointer to a VM_CRC_THREAD_STRUCT structure, type cast
as a void pointer
OUTPUT: none
RETURNS: The CRC-32 value of the supplied buffer or file
*/
DWORD WINAPI VMCrc32::CRC32ThreadProc( LPVOID lpVoid )
{
P_VM_CRC_THREAD_STRUCT pxCtrl = (P_VM_CRC_THREAD_STRUCT)lpVoid;
ULONG ulCRC = 0xFFFFFFFF;
HWND hWndProgress = NULL;
if ( ::IsWindow( pxCtrl->m_hWndProgress ) )
{
// setup the progress bar
//
hWndProgress = pxCtrl->m_hWndProgress;
::PostMessage( hWndProgress, PBM_SETPOS, 0, 0 );
::PostMessage( hWndProgress, PBM_SETRANGE32, 0, 100 );
}
if ( pxCtrl->m_pbData )
{
// calculate CRC for a buffer
//
for ( UINT iOffset = 0; iOffset < pxCtrl->m_iSize; iOffset += BUFFERSIZE )
{
pxCtrl->m_poCRC32->Calculate( pxCtrl->m_pbData + iOffset,
( pxCtrl->m_iSize - iOffset > BUFFERSIZE )
? BUFFERSIZE
: ( pxCtrl->m_iSize - iOffset ),
ulCRC );
if ( ::IsWindow( hWndProgress ) )
{
int iPercent = iOffset > pxCtrl->m_iSize
? 100 : (int)( ( (double) iOffset / (double)pxCtrl->m_iSize ) * 100 );
::PostMessage( hWndProgress, PBM_SETPOS, iPercent, 0 );
}
}
}
else
if ( pxCtrl->m_achFileName )
{
// calculate CRC for a file
//
LONGLONG lDone = 0;
UINT uiSize = BUFFERSIZE;
BYTE bBuffer[ BUFFERSIZE ];
// Open the file
//
int iFile = _tsopen( pxCtrl->m_achFileName,
_O_RDONLY | _O_SEQUENTIAL | _O_BINARY,
_SH_DENYWR );
if ( iFile != -1 )
{
// Get the file size
//
_lseeki64( iFile, 0L, SEEK_SET );
LONGLONG lLength = _lseeki64( iFile, 0L, SEEK_END );
_lseeki64( iFile, 0L, SEEK_SET );
// process the file
//
while ( uiSize == BUFFERSIZE )
{
uiSize = _read( iFile, bBuffer, BUFFERSIZE );
if ( uiSize )
{
pxCtrl->m_poCRC32->Calculate( bBuffer, uiSize, ulCRC );
if ( ::IsWindow( hWndProgress ) )
{
// update the progress bar
//
lDone += uiSize;
int iPercent = (int)( ( (long double)lDone / (long double)lLength ) * 100 );
::PostMessage( hWndProgress, PBM_SETPOS, iPercent, 0 );
}
}
}
_close( iFile );
}
}
ulCRC ^= 0xFFFFFFFF;
if ( IsWindow( hWndProgress ) )
{
// notify dialog that we are done
//
::PostMessage( ::GetParent( hWndProgress ), VM_WM_CRC_THREAD_DONE, (WPARAM)pxCtrl->m_hThread, ulCRC );
}
// clean up
// Known Problem : If the thread is prematurely terminated,
// this cleanup code is never run, resulting in a memory leak.
//
delete pxCtrl->m_pbData;
delete pxCtrl;
// return our CRC-32 value
//
return( ulCRC );
}
/* End of function "VMCrc32::CRC32ThreadProc"
/*****************************************************************************/
/*****************************************************************************/
/*
FUNCTION NAME: VMCrc32::VMCrc32
DESCRIPTION: ctor. sets up the CRC-32 reference table
INPUT: void
OUTPUT: none
RETURNS: none
*/
VMCrc32::VMCrc32( void )
{
// This is the official polynomial used by CRC-32 in PKZip, WinZip and Ethernet.
//
ULONG ulPolynomial = 0x04C11DB7;
// 256 values representing ASCII character codes.
//
for (int iOuter = 0; iOuter <= 0xFF; iOuter++ )
{
m_aulTable[ iOuter ] = Reflect( iOuter, 8 ) << 24;
for ( int iInner = 0; iInner < 8; iInner++ )
{
m_aulTable[ iOuter ] = (m_aulTable[ iOuter ] << 1) ^ (m_aulTable[ iOuter ] & (1 << 31)
? ulPolynomial : 0 );
}
m_aulTable[ iOuter ] = Reflect( m_aulTable[ iOuter ], 32 );
}
}
/* End of function "VMCrc32::VMCrc32"
/*****************************************************************************/
/*****************************************************************************/
/*
FUNCTION NAME: VMCrc32::Reflect
DESCRIPTION: used by the constructor to help set up the CRC-32 reference
table
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -