下面是完整的代码:
unit libpclamav;
(*
As taken from clamav for windows package
Pascal DLL renamed to libpclamav.dll to avoid loading wrong dll version.
Pascal DLL compiled by Rene using minGW ** issues on bzip support **
Added support for dynamic loading
*)
{**************************************************************************}
{ Partial Delphi header for clamav.h }
{ Generated Date: 2004-10-09 }
{ Generated Time: 12:48:04 }
{ }
{**************************************************************************}
interface
uses
Windows,SysUtils;
type
PPChar=^PChar;
const
ClamDLL='cygclamav-2.dll';
CL_COUNT_PRECISION = 4096;
{+// return codes*/ }
CL_CLEAN = 0; {/* virus not found*/}
CL_VIRUS = 1; {/* virus found*/}
CL_EMAXREC = -100; {/* recursion level limit exceeded*/}
CL_EMAXSIZE = -101; {/* size limit exceeded*/}
CL_EMAXFILES = -102; {/* files limit exceeded*/}
CL_ERAR = -103; {/* rar handler error*/}
CL_EZIP = -104; {/* zip handler error*/}
CL_EGZIP= -105; { gzip handler error }
CL_EBZIP= -106; { bzip2 handler error }
CL_EOLE2= -107; { OLE2 handler error }
CL_EMSCOMP= -108; { MS Expand handler error }
CL_EMSCAB= -109; { MS CAB module error }
CL_EACCES= -110; { access denied }
CL_ENULLARG= -111; { null argument }
CL_ETMPFILE= -112; { tmpfile() failed }
CL_EFSYNC= -113; { fsync() failed }
CL_EMEM= -114; { memory allocation error }
CL_EOPEN= -115; { file open error }
CL_EMALFDB= -116; { malformed database }
CL_EPATSHORT= -117; { pattern too short }
CL_ETMPDIR= -118; { mkdir() failed }
CL_ECVD= -119; { not a CVD file (or broken) }
CL_ECVDEXTR= -120; { CVD extraction failure }
CL_EMD5= -121; { MD5 verification error }
CL_EDSIG= -122; { digital signature verification error }
CL_EIO= -123; { general I/O error }
CL_EFORMAT= -124; { bad format or broken file }
CL_ESUPPORT= -125; { not supported data format }
CL_ELOCKDB= -126; { can't lock DB directory }
CL_ENCINIT= -200;
CL_ENCIO= -202 ;
{/* db options */ }
CL_DB_NCORE= $1 ;
CL_DB_PHISHING= $2;
CL_DB_ACONLY= $4; {/* WARNING: only for developers */}
CL_DB_PHISHING_URLS= $8;
{/* recommended db settings */ }
CL_DB_STDOPT= CL_DB_PHISHING;
{/* scan options */ }
CL_SCAN_RAW= $0;
CL_SCAN_ARCHIVE= $1;
CL_SCAN_MAIL= $2;
CL_SCAN_OLE2= $4 ;
CL_SCAN_BLOCKENCRYPTED= $8;
CL_SCAN_HTML= $10;
CL_SCAN_PE= $20;
CL_SCAN_BLOCKBROKEN= $40 ;
CL_SCAN_MAILURL= $80 ;
CL_SCAN_BLOCKMAX= $100;
CL_SCAN_ALGORITHMIC= $200;
CL_SCAN_PHISHING_DOMAINLIST= $400;
CL_SCAN_PHISHING_BLOCKSSL= $800 ; {/* ssl mismatches, not ssl by itself*/ }
CL_SCAN_PHISHING_BLOCKCLOAK= $1000 ;
CL_SCAN_ELF= $2000 ;
CL_SCAN_PDF= $4000;
{/* recommended scan settings */ }
CL_SCAN_STDOPT= (CL_SCAN_ARCHIVE or CL_SCAN_MAIL or CL_SCAN_OLE2 or CL_SCAN_HTML or CL_SCAN_PE or CL_SCAN_ALGORITHMIC or CL_SCAN_ELF);
{/* aliases for backward compatibility */ }
CL_RAW= CL_SCAN_RAW;
CL_ARCHIVE =CL_SCAN_ARCHIVE;
CL_MAIL= CL_SCAN_MAIL;
CL_OLE2= CL_SCAN_OLE2 ;
CL_ENCRYPTED= CL_SCAN_BLOCKENCRYPTED;
type
PPcli_bm_patt=^Pcli_bm_patt;
Pcli_bm_patt = ^Tcli_bm_patt;
Tcli_bm_patt = record
pattern : PChar;
virname : PChar;
offset : PChar;
viralias : PChar;
length : Word ;
target : Word;
next : pcli_bm_patt;
end;
//struct cli_bm_patt {
// unsigned char *pattern;
// char *virname, *offset;
// const char *viralias;
// unsigned int length;
// unsigned short target;
// struct cli_bm_patt *next;
//}
Pcli_ac_patt = ^Tcli_ac_patt;
Tcli_ac_patt = record
pattern : PSmallInt;
length ,
mindist,
maxdist,
prefix_length : Word;
virname : PChar;
offset : PChar;
viralias : PChar;
sigid : Word;
parts : Word;
partno : Word;
alt : Word;
altn : PWord; //modified by linuxping
alt_pattern:Word; //modified by linuxping
typed : Word;
target : Word;
altc : PPChar; {unsigned char **altc;}
next : pcli_ac_patt;
end;
//struct cli_ac_patt {
// short int *pattern, *prefix;
// unsigned int length, mindist, maxdist, prefix_length;
// char *virname, *offset;
// const char *viralias;
// unsigned short int sigid, parts, partno, alt, *altn, alt_pattern;
// unsigned short type, target;
// unsigned char **altc;
// struct cli_ac_patt *next;
//}
PPcli_ac_node=^Pcli_ac_node;
Pcli_ac_node = ^Tcli_ac_node;
Tcli_ac_node = record
islast : Char;
list : pcli_ac_patt;
trans : array[0..255] of pcli_ac_node;
fail : pcli_ac_node;
end;
//struct cli_ac_node {
// unsigned char islast;
// struct cli_ac_patt *list;
// struct cli_ac_node *trans[256], *fail;
//};
PPcli_md5_node=^Pcli_md5_node;
Pcli_md5_node = ^Tcli_md5_node;
TCli_md5_node = record
virname : PChar;
viralias : PChar;
md5 : PChar;
size : Word ;
fp: Word;
next : pcli_md5_node;
end;
//struct cli_md5_node {
// char *virname, *viralias;
// unsigned char *md5;
// unsigned int size;
// unsigned short fp;
// struct cli_md5_node *next;
//};
Pcli_meta_node=^Tcli_meta_node;
Tcli_meta_node=record
csize, size, method:Integer;
crc32, fileno, encrypted, maxdepth:Word;
filename, virname
Char;
next
cli_meta_node;
end;
//struct cli_meta_node {
// int csize, size, method;
// unsigned int crc32, fileno, encrypted, maxdepth;
// char *filename, *virname;
// struct cli_meta_node *next;
// }
PPcli_matcher=^Pcli_matcher;
Pcli_matcher=^Tcli_matcher;
Tcli_matcher=record
maxpatlen:Word;
ac_only: Word;
bm_shift
Integer;
bm_suffix
Pcli_bm_patt;
ac_depth:Word;
ac_root
cli_ac_node;
ac_nodetable
Pcli_ac_node;
ac_partsigs, ac_nodes:Word;
end;
//struct cli_matcher {
// unsigned int maxpatlen; /* maximal length of pattern in db */
// unsigned short ac_only;
//
// /* Extended Boyer-Moore */
// int *bm_shift;
// struct cli_bm_patt **bm_suffix;
//
// /* Extended Aho-Corasick */
// unsigned int ac_depth;
// struct cli_ac_node *ac_root, **ac_nodetable;
// unsigned int ac_partsigs, ac_nodes;
//}
Pcl_engine=^Tcl_engine;
Tcl_engine=record
refcount:Word;
ncore,
sdb: word;
dboptions: Word;
{/* Roots table */}
root
Pcli_matcher;
{/* MD5 */}
md5_hlist
Pcli_md5_node;
{/* MD5 list for PE sections */}
md5_sect
cli_md5_node;
{/* Zip metadata */}
zip_mlist
cli_meta_node;
{/* RAR metadata */}
rar_mlist
cli_meta_node;
{ /* NodalCore database handle */}
ncdb
ointer;
{ /* Phishing .pdb and .wdb databases*/}
whitelist_matcher,domainlist_matcher,phishcheck,
{/* Dynamic configuration */}
dconf
ointer;
end;
//struct cl_engine {
// unsigned int refcount; /* reference counter */
// unsigned short ncore;
// unsigned short sdb;
// unsigned int dboptions;
//
// /* Roots table */
// struct cli_matcher **root;
//
// /* MD5 */
// struct cli_md5_node **md5_hlist;
//
// /* MD5 list for PE sections */
// struct cli_md5_node *md5_sect;
//
// /* Zip metadata */
// struct cli_meta_node *zip_mlist;
//
// /* RAR metadata */
// struct cli_meta_node *rar_mlist;
//
// /* NodalCore database handle */
// void *ncdb;
//
// /* Phishing .pdb and .wdb databases*/
// void *whitelist_matcher;
// void *domainlist_matcher;
// void *phishcheck;
//
// /* Dynamic configuration */
// void *dconf;
// };
Pcl_limits = ^Tcl_limits;
Tcl_limits = record
maxreclevel: Word;
maxfiles: Word;
maxmailrec,
maxratio: Word;
archivememlim: Word;
maxfilesize: LongInt;
end;
//struct cl_limits {
// unsigned int maxreclevel; /* maximum recursion level for archives */
// unsigned int maxfiles; /* maximum number of files to be scanned
// * within a single archive
// */
// unsigned int maxmailrec; /* maximum recursion level for mail files */
// unsigned int maxratio; /* maximum compression ratio */
// unsigned short archivememlim; /* limit memory usage for some unpackers */
// unsigned long int maxfilesize; /* compressed files larger than this limit
// * will not be scanned
// */
//};
//struct stat {
// _dev_t st_dev;
// _ino_t st_ino;
// unsigned short st_mode;
// short st_nlink;
// short st_uid;
// short st_gid;
// _dev_t st_rdev;
// _off_t st_size;
// time_t st_atime;
// time_t st_mtime;
// time_t st_ctime;
// };
{ PStat=TStat;
TStat=record
_dev_t:
end; }
{
struct cl_stat {
char *dir;
unsigned int entries;
struct stat *stattab;
char **statdname;
}
{ Tcl_stat=record
dir
Char;
entries:Cardinal;
stattab
stat
statdname
Pchar;
end; }
Pcl_cvd = ^Tcl_cvd;
Tcl_cvd = record
time: PChar;
version,
sigs,
fl:Word;
md5: PChar;
dsig: PChar;
builder: PChar;
stime: Word;
end;
//struct cl_cvd { /* field no. */
// char *time; /* 2 */
// unsigned int version; /* 3 */
// unsigned int sigs; /* 4 */
// unsigned int fl; /* 5 */
// char *md5; /* 6 */
// char *dsig; /* 7 */
// char *builder; /* 8 */
// unsigned int stime; /* 9 */
//};
// scan memory buffer
// TClam_scanbuff=function (const buffer: PChar;
// length: integer;
// const virname: PChar;
// root : Pointer): Integer ; cdecl;
//
//scan file
{extern int cl_scanfile(const char *filename, const char **virname, unsigned long int *scanned,
const struct cl_engine *engine, const struct cl_limits *limits, unsigned int options);}
TClam_scanfile=function (const filename: PChar;
const virname: PChar;
var scanned: Cardinal;
var engine : Tcl_engine;
limits: pcl_limits;
options: Word ): Integer ; cdecl;
{extern int cl_load(const char *path, struct cl_engine **engine, unsigned int *signo, unsigned int options);}
TClam_load=function (const path
Char; var engine: Pcl_engine;var signo
WORD;options:Word ):Integer;cdecl;
{extern const char *cl_retdbdir(void);}
TClam_retdbdir=function
Char;cdecl;
{extern struct cl_engine *cl_dup(struct cl_engine *engine);}
{/* CVD */
extern struct cl_cvd *cl_cvdhead(const char *file);
extern struct cl_cvd *cl_cvdparse(const char *head);
extern void cl_cvdfree(struct cl_cvd *cvd);
}
{
/* db dir stat functions */
extern int cl_statinidir(const char *dirname, struct cl_stat *dbstat);
extern int cl_statchkdir(const struct cl_stat *dbstat);
extern int cl_statfree(struct cl_stat *dbstat);
}
{
/* others */
extern void cl_settempdir(const char *dir, short leavetemps);
}
//scan file descriptor (open handle to file)
{extern int cl_scandesc(int desc, const char **virname, unsigned long int *scanned,
const struct cl_engine *engine, const struct cl_limits *limits, unsigned int options);}
TClam_scandesc=function (desc : integer;
const virname: PChar;
var scanned: Cardinal;
var engine : Tcl_engine;
limits: pcl_limits;
options: Word): Integer ; cdecl;
// /* software versions */
// extern unsigned int cl_retflevel(void);
// extern const char *cl_retver(void);
TClam_retflevel=function : Word ; cdecl;
TClam_retver=function : PChar ; cdecl;
// /* enable debug messages */
// extern void cl_debug(void);
TClam_debug = procedure; cdecl;
{extern int cl_build(struct cl_engine *engine);}
TClam_build=function (var engine : Tcl_engine) : integer ; cdecl;
{extern void cl_free(struct cl_engine *engine);}
TClam_free=procedure (var engine : Tcl_engine) ; cdecl;
// extern const char *cl_retdbdir(void);}
// {
// int cl_loaddbdir(const char *dirname, struct cl_engine **engine, unsigned int *signo) {
// return cli_loaddbdir(dirname, engine, signo, CL_DB_STDOPT);
// }
TClam_loaddbdir=function (const dirname: PChar; var cl_engine
cl_engine;
var signo: Pword{;var errcode : Integer}): Integer ; cdecl;
{
int cl_loaddb(const char *filename, struct cl_engine **engine, unsigned int *signo) {
return cli_load(filename, engine, signo, CL_DB_STDOPT);
}
TClam_loaddb=function (const filename: PChar; var cl_engine
cl_engine;
var signo
word{;var errcode: Integer}): Integer ; cdecl;
{ extern int cl_cvdverify(const char *file); }
TClam_cvdverify=function (const filename : PChar) : integer ; cdecl;
{ extern const char *cl_strerror(int clerror);}
TClam_strerror=function (clerror : integer) : PChar ; cdecl;
cl_node= Tcl_engine;
cl_perror= TClam_strerror;
var
//Clam_scanbuff : TClam_scanbuff;
Clam_scanfile : TClam_scanfile;
Clam_scandesc : TClam_scandesc;
Clam_retflevel : TClam_retflevel;
Clam_retver : TClam_retver;
Clam_strerror : TClam_strerror;
Clam_debug : TClam_debug;
Clam_build : TClam_build;
Clam_free : TClam_free;
Clam_loaddbdir : TClam_loaddbdir;
Clam_loaddb : TClam_loaddb;
Clam_cvdverify : TClam_cvdverify;
Clam_load:TClam_load;
Clam_retdbdir:TClam_retdbdir;
function LoadClamavDLL: Boolean;
implementation
var
LibLoaded: Boolean = False;
HDLL: THandle=0;
function LoadClamavDLL: Boolean;
var Loaded: Boolean;
function ProcAddress (Proc: String): Pointer;
begin
{$IFNDEF FPC}
Result := GetProcAddress (HDLL, PChar(Proc));
{$ELSE}
Result := GetProcedureAddress (HDLL, PChar(Proc)); //verify this call (it's not correct now).
{$ENDIF}
if not Assigned(Result) then
Loaded := False;
end;
begin
Result := LibLoaded;
if Result then
exit;
if HDLL = 0 then
begin
HDLL := SafeLoadLibrary(PAnsiChar(ClamDLL+#0));
if HDLL <> 0 then
begin
Loaded := True;
//Clam_scanbuff := ProcAddress ('clam_scanbuff');
Clam_scanfile := ProcAddress ('cl_scanfile');
Clam_scandesc := ProcAddress ('cl_scandesc');
Clam_retflevel := ProcAddress ('cl_retflevel');
Clam_retver := ProcAddress ('cl_retver');
Clam_strerror := ProcAddress ('cl_strerror');
Clam_debug := ProcAddress ('cl_debug');
Clam_build := ProcAddress ('cl_build');
Clam_free := ProcAddress ('cl_free');
Clam_loaddbdir := ProcAddress ('cl_loaddbdir');
Clam_loaddb := ProcAddress ('cl_loaddb');
Clam_cvdverify := ProcAddress ('cl_cvdverify');
Clam_load := ProcAddress ('cl_load');
Clam_retdbdir:= ProcAddress ('cl_retdbdir');
LibLoaded := Loaded;
Result := LibLoaded;
if not Result then
begin
FreeLibrary (HDLL);
HDLL := 0;
end;
end;
end;
end;
end.