***************************************************************************

CRC32.DLL Author: Jeff Simms  72200,3173  Date: June 28, 1992

Calculation routine from CRC32.100 author Gary Brown/B. Gavin
Build CRC Table routine from CRCMAN.C author unknown

Compiled under MS C7 Small Model 

*******************************************************************************

Why I wrote this...

CRC32 is the most reliable mechanism to guarantee the completeness and authenticity of a file. PKZIP uses it as does ZMODEM transfer. So what did I want to guarantee the authenticity of? My programs of course. It is too easy to take a program and open it up and change the authors name and where to send money. And change or add a few bytes here or there and some hacker may be able to turn the program into a Trojan Horse!

Anyway, enough pessimism. The idea I had was to calculate the CRC32 value of my finished program. Then store this information in some disquised way in the programs  .ini or .cfg file. Then when the program is launched use the CRC32.DLL to verify the value. If it matches okay. If not, no go, and explain why. Could by a virus, could be a hack, could be a number of things, but it isn't what it's suppose to be!

So that's the story behind CRC32.DLL, hope you find it useful.


Declare Function CRC32 Lib "CRC32.DLL" (ByVal lpFilename As String) As Long

Sample Usage:

i& = CRC32("c:\mydir\myfile.txt")
debug.print Hex$(i&)

This calculates the CRC32 value for "myfile.txt". It returns the value as long which can be converted to hex with the Hex$ function. It returns -1 if an error occurs.


Source Code:

#include <stdio.h>
#include <windows.h>
#include "crc32.h"

#define CRC32_POLYNOMIAL     0xEDB88320L

unsigned long CRCTable[ 256 ];

int FAR PASCAL LibMain( HANDLE hInstance, WORD wDataSegment,
				   WORD wHeapSize, LPSTR lpszCmdLine )
{
    if ( wHeapSize != 0 )
	UnlockData( 0 );
    return 1;
}

int FAR PASCAL WEP (int bSystemExit)
{
    return (1);
}

long __export FAR PASCAL CRC32(LPSTR nFilename)
{

    FILE *in;
    int count,i,j;
    unsigned long CRC32 = 0xFFFFFFFFL;
    unsigned long crc;
    static char buffer[6144];
    static char	nfilename[128];

    lstrcpy(nfilename,nFilename);

    for ( i = 0; i <= 255 ; i++ ) {
	crc = i;
	for ( j = 8 ; j > 0; j-- ) {
	    if ( crc & 1 )
		crc = ( crc >> 1 ) ^ CRC32_POLYNOMIAL;
	    else
		crc >>= 1;
	}
	CRCTable[ i ] = crc;
    }

	if ((in = fopen(nfilename,"rb"))==NULL)
	    return (-1);

 for ( ; ; ) {

      count = fread(buffer,sizeof(char),6144,in);
	    if (ferror(in))
		return (-1);

     if ( count == 0 )
	    break;

     __asm{
	  push	si
	  mov	ax,word ptr [CRC32]
	  mov	dx,word ptr [CRC32+2]
	  mov	cx,count
	  lea	si,buffer
	  or    cx,cx
	  jz    done_it
	 }
loop_1:
     __asm{
	 mov    bl,[si]
	 inc	si
	 xor    bh,bh
	 xor	bl,al
	 shl    bx,1
	 shl    bx,1
	 mov    al,ah
	 mov    ah,dl
	 mov    dl,dh
	 xor	dh,dh
	 xor	ax, word ptr CRCTable[bx]
	 xor	dx, word ptr CRCTable[bx+2]
	 loop   loop_1
	 }
done_it:
     __asm{
	  mov	word ptr [CRC32],ax
	  mov	word ptr [CRC32+2],dx
	  pop	si
	  }
    };

	  fclose(in);
	  CRC32 = ~CRC32;
	  return (LONG) CRC32 ;
}
