📄 scanner.c
字号:
/******************************************************************//* *//* Winpooch : Windows Watchdog *//* Copyright (C) 2004-2006 Benoit Blanchon *//* *//* This program is free software; you can redistribute it *//* and/or modify it under the terms of the GNU General Public *//* License as published by the Free Software Foundation; either *//* version 2 of the License, or (at your option) any later *//* version. *//* *//* This program is distributed in the hope that it will be *//* useful, but WITHOUT ANY WARRANTY; without even the implied *//* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR *//* PURPOSE. See the GNU General Public License for more *//* details. *//* *//* You should have received a copy of the GNU General Public *//* License along with this program; if not, write to the Free *//* Software Foundation, Inc., *//* 675 Mass Ave, Cambridge, MA 02139, USA. *//* *//******************************************************************//******************************************************************//* Build configuration *//******************************************************************/#define TRACE_LEVEL 2/******************************************************************//* Includes *//******************************************************************/// module's interface#include "Scanner.h"// standard headers#include <shlwapi.h>#include <ctype.h>#include <stdio.h>#include <tchar.h>// library's headers#include <clamav.h>// project's headers#include "Config.h"#include "FreshClam.h"#include "Strlcpy.h"#include "SpyServer.h"#include "Trace.h"/******************************************************************//* Internal constants *//******************************************************************/// how many bytes in a megabyte ?#define MEGA (1<<20)#define MAX_SPACE (1*MEGA)// antivirus names (used for configuration)static LPCTSTR szNoneName = TEXT("None") ;static LPCTSTR szClamWinName = TEXT("ClamWin") ;static LPCTSTR szKavWsName = TEXT("KavWs") ;static LPCTSTR szBitDefName = TEXT("BitDefender") ;static LPCTSTR szLibClamavName = TEXT("Libclamav") ;// constants for ClamWinstatic LPCTSTR szClamWinKey = TEXT("Software\\ClamWin") ;static LPCTSTR szClamWinPathValue = TEXT("Path") ;static LPCTSTR szClamWinConf = TEXT("ClamWin.conf") ;// constants for Kav Wsstatic LPCTSTR szKavWsKey = TEXT("Software\\KasperskyLab\\InstalledProducts\\Kaspersky Anti-Virus for Workstation") ;static LPCTSTR szKavWsFolderValue = TEXT("Folder") ;static LPCTSTR szKavWsExe = TEXT("KAVShell.exe") ;// constants for BitDefenderstatic LPCTSTR szBitDefKey = TEXT("SOFTWARE\\Softwin") ;static LPCTSTR szBitDefFolderValue = TEXT("BitDefender Scan Server") ;static LPCTSTR szBitDefExe = TEXT("bdc.exe") ;/******************************************************************//* Internal data types *//******************************************************************/typedef struct { TCHAR szScanner[MAX_PATH] ; TCHAR szDatabase[MAX_PATH] ;} CLAMWINCONF ;typedef struct { TCHAR szScanner[MAX_PATH] ;} KAVWSCONF ;typedef struct { TCHAR szScanner[MAX_PATH] ; TCHAR szFolder[MAX_PATH] ;} BITDEFCONF ;typedef struct { unsigned int options ; struct cl_limits limits ; struct cl_engine *engine ; TCHAR szScanner[MAX_PATH] ;} LIBCLAMAVCONF ;typedef struct { UINT nScanner ; CLAMWINCONF clamwinconf ; KAVWSCONF kavwsconf ; BITDEFCONF bitdefconf ; LIBCLAMAVCONF libclamavconf;} INTERNALDATA ;/******************************************************************//* Internal data *//******************************************************************/static INTERNALDATA g_data ;/******************************************************************//* Internal functions *//******************************************************************/BOOL _Scanner_ClamWin_Configure (CLAMWINCONF*) ;UINT _Scanner_ClamWin_ScanFile (CLAMWINCONF*, LPCTSTR, LPTSTR szOutput, UINT nOutputMax, DWORD nPriorityClass) ;BOOL _Scanner_ClamWin_FindConfFilePath (LPTSTR) ;BOOL _Scanner_KavWs_Configure (KAVWSCONF*) ;UINT _Scanner_KavWs_ScanFile (KAVWSCONF*, LPCTSTR, LPTSTR szOutput, UINT nOutputMax, DWORD nPriorityClass) ;BOOL _Scanner_BitDef_Configure (BITDEFCONF*) ;UINT _Scanner_BitDef_ScanFile (BITDEFCONF*, LPCTSTR, LPTSTR szOutput, UINT nOutputMax, DWORD nPriorityClass) ;BOOL _Scanner_LibClamav_Configure (LIBCLAMAVCONF*) ;UINT _Scanner_LibClamav_ScanFile (LIBCLAMAVCONF*, LPCTSTR, LPTSTR szOutput, UINT nOutputMax) ;BOOL _Scanner_LibClamav_LoadDatabase (LIBCLAMAVCONF*) ;VOID _Scanner_LibClamav_DatabaseUpdated () ;/******************************************************************//* Exported function : Init *//******************************************************************/BOOL Scanner_Init (){ LPCTSTR szConfigScanner ; BOOL bResult ; TRACE ; // // Which antivirus ? // // read configuration szConfigScanner = Config_GetString(CFGSTR_ANTIVIRUS) ; // -> NULL, internal antirivus if( ! szConfigScanner ) { if( _Scanner_LibClamav_Configure (&g_data.libclamavconf) ) g_data.nScanner = SCANNER_LIBCLAMAV ; else g_data.nScanner = SCANNER_NONE ; bResult = TRUE ; } // -> ClamWin else if( !_tcsicmp(szClamWinName,szConfigScanner) ) { bResult = _Scanner_ClamWin_Configure (&g_data.clamwinconf) ; g_data.nScanner = SCANNER_CLAMWIN ; } // -> Kaspersky WS ? else if( !_tcsicmp(szKavWsName,szConfigScanner) ) { bResult = _Scanner_KavWs_Configure (&g_data.kavwsconf) ; g_data.nScanner = SCANNER_KASPERSKY_WS ; } // -> BitDefender ? else if( !_tcsicmp(szBitDefName,szConfigScanner) ) { bResult = _Scanner_BitDef_Configure (&g_data.bitdefconf) ; g_data.nScanner = SCANNER_BITDEFENDER ; } // -> Libclamav ? else if( !_tcsicmp(szLibClamavName,szConfigScanner) ) { bResult = _Scanner_LibClamav_Configure (&g_data.libclamavconf) ; g_data.nScanner = SCANNER_LIBCLAMAV ; } // -> None else if( !_tcsicmp(szNoneName,szConfigScanner) ) { g_data.nScanner = SCANNER_NONE ; bResult = TRUE ; } // -> Other else bResult = FALSE ; // if failed, then set to "none" if( ! bResult ) g_data.nScanner = SCANNER_NONE ; return bResult ;}/******************************************************************//* Exported function : Uninit *//******************************************************************/VOID Scanner_Uninit (){ TRACE ;}/******************************************************************//* Exported function *//******************************************************************/BOOL Scanner_SetScanner (UINT nScanner){ BOOL bResult = FALSE ; TRACE ; switch( nScanner ) { case SCANNER_CLAMWIN: bResult = _Scanner_ClamWin_Configure (&g_data.clamwinconf) ; break ; case SCANNER_KASPERSKY_WS: bResult = _Scanner_KavWs_Configure (&g_data.kavwsconf) ; break ; case SCANNER_BITDEFENDER: bResult = _Scanner_BitDef_Configure (&g_data.bitdefconf) ; break ; case SCANNER_LIBCLAMAV: bResult = _Scanner_LibClamav_Configure (&g_data.libclamavconf) ; break ; case SCANNER_NONE: bResult = TRUE ; break ; } g_data.nScanner = bResult ? nScanner : SCANNER_NONE ; // update config switch( g_data.nScanner ) { case SCANNER_CLAMWIN: Config_SetString (CFGSTR_ANTIVIRUS, szClamWinName) ; break ; case SCANNER_KASPERSKY_WS: Config_SetString (CFGSTR_ANTIVIRUS, szKavWsName) ; break ; case SCANNER_BITDEFENDER: Config_SetString (CFGSTR_ANTIVIRUS, szBitDefName) ; break ; case SCANNER_LIBCLAMAV: Config_SetString (CFGSTR_ANTIVIRUS, szLibClamavName) ; break ; default: Config_SetString (CFGSTR_ANTIVIRUS, szNoneName) ; } Config_SaveString (CFGSTR_ANTIVIRUS) ; // tell the spy server that he should not scan this file SpySrv_SetScannerExePath (Scanner_GetScannerExe()) ; return bResult ;}/******************************************************************//* Exported function : IsConfigured *//******************************************************************/BOOL Scanner_IsConfigured (){ TRACE ; return g_data.nScanner!=SCANNER_NONE ;}/******************************************************************//* Exported function *//******************************************************************/UINT Scanner_GetScanner (){ TRACE ; return g_data.nScanner ;}/******************************************************************//* Exported function : IsScanner *//******************************************************************/BOOL Scanner_IsScanner (LPCTSTR szPath){ LPCTSTR szScanner = Scanner_GetScannerExe () ; return 0==_tcsicmp(szScanner,szPath) ;}/******************************************************************//* Exported function *//******************************************************************/LPCTSTR Scanner_GetScannerExe (){ LPCTSTR szScanner ; switch( g_data.nScanner ) { case SCANNER_CLAMWIN: szScanner = g_data.clamwinconf.szScanner ; break ; case SCANNER_KASPERSKY_WS: szScanner = g_data.kavwsconf.szScanner ; break ; case SCANNER_BITDEFENDER: szScanner = g_data.bitdefconf.szScanner ; break ; case SCANNER_LIBCLAMAV: szScanner = g_data.libclamavconf.szScanner ; break ; default: return NULL ; } return szScanner ;}/******************************************************************//* Exported function : ScanFile *//******************************************************************/UINT Scanner_ScanFile (LPCTSTR szPath, LPTSTR szOutput, UINT nOutputMax, BOOL bBackground){ TRACE_INFO ("File = %s\n", szPath) ; // avoid scanning the scanner if( Scanner_IsScanner(szPath) ) return FALSE ; switch( g_data.nScanner ) { case SCANNER_CLAMWIN: return _Scanner_ClamWin_ScanFile (&g_data.clamwinconf, szPath, szOutput, nOutputMax, bBackground ? IDLE_PRIORITY_CLASS : HIGH_PRIORITY_CLASS) ; case SCANNER_KASPERSKY_WS: return _Scanner_KavWs_ScanFile (&g_data.kavwsconf, szPath, szOutput, nOutputMax, bBackground ? IDLE_PRIORITY_CLASS : HIGH_PRIORITY_CLASS) ; case SCANNER_BITDEFENDER: return _Scanner_BitDef_ScanFile (&g_data.bitdefconf, szPath, szOutput, nOutputMax, bBackground ? IDLE_PRIORITY_CLASS : HIGH_PRIORITY_CLASS) ; case SCANNER_LIBCLAMAV: return _Scanner_LibClamav_ScanFile (&g_data.libclamavconf, szPath, szOutput, nOutputMax) ; } return SCANNER_NONE ;}/******************************************************************//* Internal function *//******************************************************************/BOOL _Scanner_ClamWin_FindConfFilePath (LPTSTR szPath){ HKEY hkey ; LONG nResult ; DWORD dwType, dwSize ; UINT nLen ; TCHAR szValue[MAX_PATH] ; // open key on HKCU nResult = RegOpenKeyEx (HKEY_CURRENT_USER, szClamWinKey, 0, KEY_READ, &hkey) ; if( ERROR_SUCCESS!=nResult ) { TRACE_INFO (TEXT("Failed to open key HKCU\\%s (error=%d)\n"), szClamWinKey, nResult) ; // else try on HKLM nResult = RegOpenKeyEx (HKEY_LOCAL_MACHINE, szClamWinKey, 0, KEY_READ, &hkey) ; if( ERROR_SUCCESS!=nResult ) { TRACE_INFO (TEXT("Failed to open key HKLM\\%s (error=%d)\n"), szClamWinKey, nResult) ; return FALSE ; } } // read install path dwSize = sizeof(szValue) ; nResult = RegQueryValueEx (hkey, szClamWinPathValue, NULL, &dwType, (BYTE*)szValue, &dwSize); // ok ? if( ERROR_SUCCESS!=nResult || dwSize==0 ) { TRACE_ERROR (TEXT("Failed to read ClamWin path (error=%d)\n"),nResult) ; CloseHandle(hkey) ; return FALSE ; } // expand env strings nLen = ExpandEnvironmentStrings (szValue, szPath, MAX_PATH) ; if( ! nLen ) { TRACE_ERROR (TEXT("ExpandEnvironmentStrings failed (error=%d)\n"), GetLastError()) ; CloseHandle(hkey) ; return FALSE ; } // get conf file path _tcscat (szPath, TEXT("\\")) ; _tcscat (szPath, szClamWinConf) ; CloseHandle(hkey) ; return TRUE ;}/******************************************************************//* Internal function *//******************************************************************/BOOL _Scanner_ClamWin_Configure (CLAMWINCONF * pConf){ TCHAR szConfFile[MAX_PATH] ; TCHAR szLine[1024] ; FILE * fp ; if( ! _Scanner_ClamWin_FindConfFilePath(szConfFile) ) { TRACE_ERROR (TEXT("Failed to find ClamWin configuration file\n")) ; return FALSE ; } TRACE_INFO (TEXT("ClamWin configuration file : %s\n"), szConfFile) ; fp = _tfopen (szConfFile, TEXT("rt")) ; if( ! fp ) { TRACE_ERROR (TEXT("Failed to open ClamWin configuration file.\n")) ; return FALSE ; } while( _fgetts(szLine,1024,fp) ) { int i ; int iNameFirst, iNameLast ; int iValueFirst, iValueLast ; LPCTSTR szName, szValue ; //TRACE_INFO (TEXT("%s"), szLine) ; i = 0 ; // skip spaces while( _istspace(szLine[i]) ) i++ ; // is the line empty ? if( ! szLine[i] ) continue ; // is it a comment ? if( szLine[i]==TEXT('#') ) continue ; // is it a section ? if( szLine[i]==TEXT('[') ) continue ; iNameFirst = i ; // look for '=' while( szLine[i] && szLine[i]!=TEXT('=') ) i++ ; // end of line ? if( ! szLine[i] ) continue ; iNameLast = i-1 ; // remove ending spaces
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -