/* ** (c) Yasiukevich M.M. 1996, 2000 yasiukevich@mail.ru ** ** Calculation of 32-bit CRC. (File sharing version) ** ** Based on material from Borland Source Library. ** Adapted to sharing file system. LFN not support. ** All file name must be a short name. ** ** ** EXAMPLE: ** ** --8<----------------------------- ** ** #include "crc32shr.c" ** #include // It is not necessary because stdio.h included in ** // crc32shr.c ** ** void main (void) ** { ** unsigned long CRC; ** char *FName1="C:\\AUTOEXEC.BAT"; ** char *FName2="C:\\MSDOS.SYS"; ** ** InitMagic(); ** CRCFile(FName1, &CRC); ** printf("C:\\AUTOEXEC.BAT CRC:%lu\n",CRC); ** CRCFile(FName2, &CRC); ** printf("C:\\MSDOS.SYS CRC:%lu\n",CRC); ** } ** ** --8<----------------------------- */ #include #include #include #include #include #include #include #include #if defined(__LARGE__) #elif #error Modul CRC32 was test only in LARGE model ! #endif const K63 = 63*1024; long near Magicon = 0xEDB88320L; // Constant used to fill array Magic long near Magic[256]; // Table used to translate bytes to CRC void *pBuff = NULL; // Work buffer /*-------------------------------------------------------------------- * Initalisation of table and allocating buffer. * Opening of using module. */ int InitMagic(void) { asm { std // Set direction flag <- push ds pop es mov di, OFFSET Magic + 0x03FE // Last WORD of the array push bp mov bp, 0xFF }; im0: asm { mov cx, 8 mov dx, bp xor ax, ax }; im1: asm { shr ax, 1 rcr dx, 1 jnc im2 xor dx, WORD PTR Magicon xor ax, WORD PTR Magicon + 2 }; im2: asm { loop im1 // if cx > 0 goto im1; stosw // mov word ptr es:[di],ax; di--; xchg ax,dx // swap ax,dx; stosw // mov word ptr es:[di],ax; di--; dec bp // bp--; jns im0 // if SF=0 goto im0; pop bp }; if ((pBuff = malloc(K63)) == NULL) { fprintf( stdout, "\n*** Error: %s InitMagic() - insufficient memory.\n", __FILE__ ); return 1; } return 0; }; /*-------------------------------------------------------------------- * * Closing of using module. */ void FinishMagic(void) { free(pBuff); pBuff = NULL; } /*-------------------------------------------------------------------- */ void InitCRC(unsigned long *CRC) { *CRC = 0xFFFFFFFF; } /*-------------------------------------------------------------------- */ void IncCRC(void *pBuff,unsigned int Count, unsigned long* pCRC) { asm { les si, pCRC mov cx, es:[si] mov dx, es:[si+2] mov di, OFFSET Magic les si, pBuff cld push bp mov bp, Count inc bp jmp SHORT ic1 }; ic0: asm { xor ax,ax mov al, byte ptr es:[si] inc si mov bx, ax xor bl, cl mov cl, ch mov ch, dl mov dl, dh mov dh, bh shl bx, 1 shl bx, 1 xor cx, [bx+di] xor dx, [bx+di+2] test si, si jnz ic1 mov ax, es add ax, 0x1000 mov es, ax }; ic1: asm { dec bp jnz ic0 pop bp les si, pCRC mov es:[si], cx mov es:[si+2], dx }; }; /*-------------------------------------------------------------------- */ void FinishCRC (unsigned long *CRC) { asm { les si, CRC mov ax, es:[si] mov bx, es:[si+2] not ax not bx mov word ptr es:[si], ax mov word ptr es:[si+2], bx }; }; /*-------------------------------------------------------------------- * Calculate CRC-32 of a given file through disposed buffer; * returns 0 if file is OK, IOResult on file error, $FFFF on BuffLen = 0 */ int CRCFileB(char *FName,void *Buff, unsigned int BuffLen,unsigned long *CRC) { long Rest; unsigned int Portion, IOError; int status, handle; FILE *fp; struct ffblk ffblk; if ( BuffLen==0 ) { CRC=0; return 0xFFFF; } if ( findfirst( FName, &ffblk, 0xFFFF )!=0 ) { *CRC=0; return errno; } if ( (handle = sopen( FName, O_RDONLY+O_BINARY, SH_DENYNO, S_IREAD)) == -1 ) { *CRC=0; return errno; }; status = access(FName, 4); if ( status ) { close(handle); *CRC=0; return errno; } InitCRC(CRC); Rest = ffblk.ff_fsize; while (Rest > 0) { Portion=BuffLen; if ( BuffLen>Rest ) { Portion = Rest; } read( handle, Buff, Portion ); IncCRC( Buff, Portion, CRC ); Rest -= Portion; }; close(handle); FinishCRC(CRC); return 0; } /*-------------------------------------------------------------------- * Calculate CRC-32 of a given file using GetMem for 63Kb buffer; * Returns 0 if file is OK, IOResult on file error */ int CRCFile( char *FName, unsigned long *CRC ) { if ( pBuff == NULL ) { fprintf( stdout, "\n*** Error: %s CRCFile() - Use InitMagic before call CRCFile().\n", __FILE__ ); return 0xFFFF; } return CRCFileB(FName,pBuff,K63,CRC);; };