diff --git a/ClamAV.Managed/ClamAV.Managed.csproj b/ClamAV.Managed/ClamAV.Managed.csproj index bb1b94b..355acae 100644 --- a/ClamAV.Managed/ClamAV.Managed.csproj +++ b/ClamAV.Managed/ClamAV.Managed.csproj @@ -50,6 +50,7 @@ + diff --git a/ClamAV.Managed/ClamEngine.Settings.cs b/ClamAV.Managed/ClamEngine.Settings.cs new file mode 100644 index 0000000..6fb955c --- /dev/null +++ b/ClamAV.Managed/ClamEngine.Settings.cs @@ -0,0 +1,443 @@ +/* + * ClamAV.Managed - Managed bindings for ClamAV + * Copyright (C) 2011, 2013-2016 Rupert Muchembled + * + * 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., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +using System; +using System.Runtime.InteropServices; + +namespace ClamAV.Managed +{ + public partial class ClamEngine + { + #region Engine Settings + + /// + /// Get a numerical settings value. + /// + /// Setting key. + /// Setting value. + private long EngineGetNum(UnsafeNativeMethods.cl_engine_field setting) + { + int error = 0; + long numValue = UnsafeNativeMethods.cl_engine_get_num(_engine, setting, ref error); + + if (error != UnsafeNativeMethods.CL_SUCCESS) + throw new ClamException(error, ErrorString(error)); + + return numValue; + } + + /// + /// Set a numerical setting value. + /// + /// Setting key. + /// Setting value. + private void EngineSetNum(UnsafeNativeMethods.cl_engine_field setting, long value) + { + int error = UnsafeNativeMethods.cl_engine_set_num(_engine, setting, value); + + if (error != UnsafeNativeMethods.CL_SUCCESS) + throw new ClamException(error, ErrorString(error)); + } + + /// + /// Get a string setting value. + /// + /// Setting key. + /// Setting value. + private string EngineGetStr(UnsafeNativeMethods.cl_engine_field setting) + { + int error = 0; + IntPtr strPtr = UnsafeNativeMethods.cl_engine_get_str(_engine, setting, ref error); + + if (error != UnsafeNativeMethods.CL_SUCCESS) + throw new ClamException(error, ErrorString(error)); + + return Marshal.PtrToStringAnsi(strPtr); + } + + /// + /// Set a string setting value. + /// + /// Setting key. + /// Setting value. + private void EngineSetStr(UnsafeNativeMethods.cl_engine_field setting, string value) + { + int error = UnsafeNativeMethods.cl_engine_set_str(_engine, setting, value); + + if (error != UnsafeNativeMethods.CL_SUCCESS) + throw new ClamException(error, ErrorString(error)); + } + + /// + /// Maximum amount of data in a file to be scanned. + /// + public ulong MaxScanSize + { + get { return (ulong) EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_SCANSIZE); } + set { EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_SCANSIZE, (long) value); } + } + + /// + /// Maximum file size to be scanned. + /// + public ulong MaxFileSize + { + get { return (ulong) EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_FILESIZE); } + set { EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_FILESIZE, (long) value); } + } + + /// + /// Maximum recursion depth. + /// + public uint MaxRecursion + { + get { return (uint) EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_RECURSION); } + set { EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_RECURSION, (long) value); } + } + + /// + /// Maximum number of files to scan inside an archive or container. + /// + public uint MaxFiles + { + get { return (uint) EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_FILES); } + set { EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_FILES, (long) value); } + } + + /// + /// Minimum count of credit card numbers to trigger a detection. + /// + public uint MinCCCount + { + get { return (uint) EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MIN_CC_COUNT); } + set { EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MIN_CC_COUNT, (long) value); } + } + + /// + /// Minimum count of SSNs to trigger a detection. + /// + public uint MinSSNCount + { + get { return (uint) EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MIN_SSN_COUNT); } + set { EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MIN_SSN_COUNT, (long) value); } + } + + /// + /// Potentially unwanted application categories. + /// + public string PuaCategories + { + get { return EngineGetStr(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_PUA_CATEGORIES); } + set { EngineSetStr(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_PUA_CATEGORIES, value); } + } + + /// + /// Database options. + /// + public LoadOptions DatabaseOptions + { + get { return (LoadOptions) EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_DB_OPTIONS); } + set { EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_DB_OPTIONS, (long) value); } + } + + /// + /// Database version. + /// + public uint DatabaseVersion + { + get { return (uint) EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_DB_VERSION); } + set { EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_DB_VERSION, (long) value); } + } + + /// + /// Database time as a UNIX timestamp. + /// + public uint DatabaseTime + { + get { return (uint) EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_DB_TIME); } + set { EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_DB_TIME, (long) value); } + } + + /// + /// Only use Aho-Corasick pattern matcher. + /// + public uint ACOnly + { + get { return (uint) EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_AC_ONLY); } + set { EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_AC_ONLY, (long) value); } + } + + /// + /// Minimum trie depth for AC algorithm. + /// + public uint ACMinDepth + { + get { return (uint) EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_AC_MINDEPTH); } + set { EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_AC_MINDEPTH, (long) value); } + } + + /// + /// Maximum trie depth for AC algorithm. + /// + public uint ACMaxDepth + { + get { return (uint) EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_AC_MAXDEPTH); } + set { EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_AC_MAXDEPTH, (long) value); } + } + + /// + /// Path to temporary directory. + /// + public string TempDir + { + get { return EngineGetStr(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_TMPDIR); } + set { EngineSetStr(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_TMPDIR, value); } + } + + /// + /// Automatically delete temporary files. + /// + public uint KeepTempFiles + { + get { return (uint) EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_KEEPTMP); } + set { EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_KEEPTMP, (long) value); } + } + + /// + /// Bytecode security mode. + /// + public BytecodeSecurity BytecodeSecurity + { + get + { + return (BytecodeSecurity) EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_BYTECODE_SECURITY); + } + set { EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_BYTECODE_SECURITY, (long) value); } + } + + /// + /// Bytecode timeout. + /// + public uint BytecodeTimeout + { + get { return (uint) EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_BYTECODE_TIMEOUT); } + set { EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_BYTECODE_TIMEOUT, (long) value); } + } + + /// + /// Bytecode mode. + /// + public BytecodeMode BytecodeMode + { + get { return (BytecodeMode) EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_BYTECODE_MODE); } + set { EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_BYTECODE_MODE, (long) value); } + } + + /// + /// Maximum size file to check for embedded PE. + /// + public ulong MaxEmbeddedPE + { + get { return (ulong) EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_EMBEDDEDPE); } + set { EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_EMBEDDEDPE, (long) value); } + } + + /// + /// Maximum size of HTML file to normalize. + /// + public ulong MaxHtmlNormalize + { + get { return (ulong) EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_HTMLNORMALIZE); } + set { EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_HTMLNORMALIZE, (long) value); } + } + + /// + /// Maximum size of normalized HTML file to scan. + /// + public ulong MaxHtmlNoTags + { + get { return (ulong) EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_HTMLNOTAGS); } + set { EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_HTMLNOTAGS, (long) value); } + } + + /// + /// Maximum size of script file to normalize. + /// + public ulong MaxScriptNormalize + { + get { return (ulong) EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_SCRIPTNORMALIZE); } + set { EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_SCRIPTNORMALIZE, (long) value); } + } + + /// + /// Maximum size zip to type reanalyze. + /// + public ulong MaxZipTypeRcg + { + get { return (ulong) EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_ZIPTYPERCG); } + set { EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_ZIPTYPERCG, (long) value); } + } + + /// + /// This option causes memory or nested map scans to dump the content to disk. + /// + public bool ForceToDisk + { + get { return EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_FORCETODISK) != 0; } + set { EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_FORCETODISK, value ? 1 : 0); } + } + + /// + /// This option allows you to disable the caching feature of the engine. By + /// default, the engine will store an MD5 in a cache of any files that are + /// not flagged as virus or that hit limits checks. Disabling the cache will + /// have a negative performance impact on large scans. + /// + public bool DisableCache + { + get { return EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_DISABLE_CACHE) != 0; } + set { EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_DISABLE_CACHE, value ? 1 : 0); } + } + + /// + /// Disable submission of PE section statistical data. + /// + public bool DisablePeStats + { + get { return EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_DISABLE_PE_STATS) != 0; } + set { EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_DISABLE_PE_STATS, value ? 1 : 0); } + } + + /// + /// Timeout in seconds to timeout communication with the stats server. + /// + public uint StatsTimeout + { + get { return (uint) EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_STATS_TIMEOUT); } + set { EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_STATS_TIMEOUT, (long) value); } + } + + /// + /// This option sets the maximum number of partitions of a raw disk image to be scanned. + /// Raw disk images with more partitions than this value will have up to the value number partitions scanned. + /// Negative values are not allowed. + /// + /// WARNING: setting this limit too high may result in severe damage or impact performance. + /// + public uint MaxPartitions + { + get { return (uint) EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_PARTITIONS); } + set { EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_PARTITIONS, (long) value); } + } + + /// + /// This option sets the maximum number of icons within a PE to be scanned. + /// PE files with more icons than this value will have up to the value number icons scanned. + /// Negative values are not allowed. + /// + /// WARNING: setting this limit too high may result in severe damage or impact performance. + /// + public uint MaxIconSpe + { + get { return (uint) EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_ICONSPE); } + set { EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_ICONSPE, value); } + } + + /// + /// This option sets the maximum recursive calls to HWP3 parsing function. + /// HWP3 files using more than this limit will be terminated and alert the user. + /// Scans will be unable to scan any HWP3 attachments if the recursive limit is reached. + /// Negative values are not allowed. + /// + /// WARNING: setting this limit too high may result in severe damage or impact performance. + /// + public uint MaxRecHwp3 + { + get { return (uint) EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_RECHWP3); } + set { EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_RECHWP3, value); } + } + + /// + /// This clamscan option is currently for testing only. It sets the engine parameter CL_ENGINE_TIME_LIMIT. The value is in milliseconds. + /// + public uint TimeLimit + { + get { return (uint) EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_TIME_LIMIT); } + set { EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_TIME_LIMIT, value); } + } + + /// + /// This option sets the maximum calls to the PCRE match function during an instance of regex matching. + /// Instances using more than this limit will be terminated and alert the user but the scan will continue. + /// For more information on match_limit, see the PCRE documentation. + /// + /// Negative values are not allowed. + /// + /// WARNING: setting this limit too high may severely impact performance. + /// + public ulong PcreMatchLimit + { + get { return (ulong) EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_PCRE_MATCH_LIMIT); } + set { EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_PCRE_MATCH_LIMIT, (long) value); } + } + + /// + /// This option sets the maximum recursive calls to the PCRE match function during an instance of regex matching. + /// Instances using more than this limit will be terminated and alert the user but the scan will continue. + /// For more information on match_limit_recursion, see the PCRE documentation. + /// Negative values are not allowed and values > PCREMatchLimit are superfluous. + /// + /// WARNING: setting this limit too high may severely impact performance. + /// + public ulong PcreRecMatchLimit + { + get { return (ulong) EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_PCRE_RECMATCH_LIMIT); } + set { EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_PCRE_RECMATCH_LIMIT, (long) value); } + } + + /// + /// + /// + public ulong PcreMaxFilesize + { + get { return (ulong) EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_PCRE_MAX_FILESIZE); } + set { EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_FILESIZE, (long) value); } + } + + /// + /// + /// + public bool DisablePeCerts + { + get { return EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_DISABLE_PE_CERTS) != 0; } + set { EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_DISABLE_PE_CERTS, value ? 1 : 0); } + } + + /// + /// Dump PE certificates. + /// + public bool PeDumpCerts + { + get { return EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_PE_DUMPCERTS) != 0; } + set { EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_PE_DUMPCERTS, value ? 1 : 0); } + } + + #endregion + } +} \ No newline at end of file diff --git a/ClamAV.Managed/ClamEngine.cs b/ClamAV.Managed/ClamEngine.cs index fa5bf31..a5901cc 100644 --- a/ClamAV.Managed/ClamEngine.cs +++ b/ClamAV.Managed/ClamEngine.cs @@ -27,14 +27,14 @@ namespace ClamAV.Managed /// /// Encapsulates an instance of the ClamAV engine. /// - public class ClamEngine : IClamEngine + public partial class ClamEngine : IClamEngine { #region Global Initialization /// /// Whether the ClamAV library has been globally initialized. /// - private static bool _initialized = false; + private static bool _initialized; /// /// Global initialization method to load the ClamAV library into the process. @@ -96,10 +96,7 @@ private static string UnmarshalString(IntPtr ptr) /// /// Handle to the unmanaged ClamAV engine belonging to this instance. /// - public IntPtr Handle - { - get { return _engine; } - } + public IntPtr Handle => _engine; /// /// Cached ClamAV version string. @@ -109,16 +106,8 @@ public IntPtr Handle /// /// ClamAV engine version string. /// - public static string Version - { - get - { - if (_clamVersion == null) - _clamVersion = UnmarshalString(UnsafeNativeMethods.cl_retver()); - - return _clamVersion; - } - } + public static string Version => + _clamVersion ?? (_clamVersion = UnmarshalString(UnsafeNativeMethods.cl_retver())); /// /// Cached database directory path. @@ -128,645 +117,8 @@ public static string Version /// /// ClamAV hard-coded default database directory. /// - public string DatabaseDirectory - { - get - { - if (_databaseDirectory == null) - _databaseDirectory = UnmarshalString(UnsafeNativeMethods.cl_retdbdir()); - - return _databaseDirectory; - } - } - - #endregion - - #region Engine Settings - - /// - /// Get a numerical settings value. - /// - /// Setting key. - /// Setting value. - private long EngineGetNum(UnsafeNativeMethods.cl_engine_field setting) - { - int error = 0; - long numValue = UnsafeNativeMethods.cl_engine_get_num(_engine, setting, ref error); - - if (error != UnsafeNativeMethods.CL_SUCCESS) - throw new ClamException(error, ErrorString(error)); - - return numValue; - } - - /// - /// Set a numerical setting value. - /// - /// Setting key. - /// Setting value. - private void EngineSetNum(UnsafeNativeMethods.cl_engine_field setting, long value) - { - int error = UnsafeNativeMethods.cl_engine_set_num(_engine, setting, value); - - if (error != UnsafeNativeMethods.CL_SUCCESS) - throw new ClamException(error, ErrorString(error)); - } - - /// - /// Get a string setting value. - /// - /// Setting key. - /// Setting value. - private string EngineGetStr(UnsafeNativeMethods.cl_engine_field setting) - { - int error = 0; - IntPtr strPtr = UnsafeNativeMethods.cl_engine_get_str(_engine, setting, ref error); - - if (error != UnsafeNativeMethods.CL_SUCCESS) - throw new ClamException(error, ErrorString(error)); - - return Marshal.PtrToStringAnsi(strPtr); - } - - /// - /// Set a string setting value. - /// - /// Setting key. - /// Setting value. - private void EngineSetStr(UnsafeNativeMethods.cl_engine_field setting, string value) - { - int error = UnsafeNativeMethods.cl_engine_set_str(_engine, setting, value); - - if (error != UnsafeNativeMethods.CL_SUCCESS) - throw new ClamException(error, ErrorString(error)); - } - - /// - /// Maximum amount of data in a file to be scanned. - /// - public ulong MaxScanSize - { - get - { - return (ulong)EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_SCANSIZE); - } - set - { - EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_SCANSIZE, (long)value); - } - } - - /// - /// Maximum file size to be scanned. - /// - public ulong MaxFileSize - { - get - { - return (ulong)EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_FILESIZE); - } - set - { - EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_FILESIZE, (long)value); - } - } - - /// - /// Maximum recursion depth. - /// - public uint MaxRecursion - { - get - { - return (uint)EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_RECURSION); - } - set - { - EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_RECURSION, (long)value); - } - } - - /// - /// Maximum number of files to scan inside an archive or container. - /// - public uint MaxFiles - { - get - { - return (uint)EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_FILES); - } - set - { - EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_FILES, (long)value); - } - } - - /// - /// Minimum count of credit card numbers to trigger a detection. - /// - public uint MinCCCount - { - get - { - return (uint)EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MIN_CC_COUNT); - } - set - { - EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MIN_CC_COUNT, (long)value); - } - } - - /// - /// Minimum count of SSNs to trigger a detection. - /// - public uint MinSSNCount - { - get - { - return (uint)EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MIN_SSN_COUNT); - } - set - { - EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MIN_SSN_COUNT, (long)value); - } - } - - /// - /// Potentially unwanted application categories. - /// - public string PuaCategories - { - get - { - return EngineGetStr(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_PUA_CATEGORIES); - } - set - { - EngineSetStr(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_PUA_CATEGORIES, value); - } - } - - /// - /// Database options. - /// - public LoadOptions DatabaseOptions - { - get - { - return (LoadOptions)EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_DB_OPTIONS); - } - set - { - EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_DB_OPTIONS, (long)value); - } - } - - /// - /// Database version. - /// - public uint DatabaseVersion - { - get - { - return (uint)EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_DB_VERSION); - } - set - { - EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_DB_VERSION, (long)value); - } - } - - /// - /// Database time as a UNIX timestamp. - /// - public uint DatabaseTime - { - get - { - return (uint)EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_DB_TIME); - } - set - { - EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_DB_TIME, (long)value); - } - } - - /// - /// Only use Aho-Corasick pattern matcher. - /// - public uint ACOnly - { - get - { - return (uint)EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_AC_ONLY); - } - set - { - EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_AC_ONLY, (long)value); - } - } - - /// - /// Minimum trie depth for AC algorithm. - /// - public uint ACMinDepth - { - get - { - return (uint)EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_AC_MINDEPTH); - } - set - { - EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_AC_MINDEPTH, (long)value); - } - } - - /// - /// Maximum trie depth for AC algorithm. - /// - public uint ACMaxDepth - { - get - { - return (uint)EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_AC_MAXDEPTH); - } - set - { - EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_AC_MAXDEPTH, (long)value); - } - } - - /// - /// Path to temporary directory. - /// - public string TempDir - { - get - { - return EngineGetStr(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_TMPDIR); - } - set - { - EngineSetStr(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_TMPDIR, value); - } - } - - /// - /// Automatically delete temporary files. - /// - public uint KeepTempFiles - { - get - { - return (uint)EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_KEEPTMP); - } - set - { - EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_KEEPTMP, (long)value); - } - } - - /// - /// Bytecode security mode. - /// - public BytecodeSecurity BytecodeSecurity - { - get - { - return (BytecodeSecurity)EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_BYTECODE_SECURITY); - } - set - { - EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_BYTECODE_SECURITY, (long)value); - } - } - - /// - /// Bytecode timeout. - /// - public uint BytecodeTimeout - { - get - { - return (uint)EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_BYTECODE_TIMEOUT); - } - set - { - EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_BYTECODE_TIMEOUT, (long)value); - } - } - - /// - /// Bytecode mode. - /// - public BytecodeMode BytecodeMode - { - get - { - return (BytecodeMode)EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_BYTECODE_MODE); - } - set - { - EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_BYTECODE_MODE, (long)value); - } - } - - /// - /// Maximum size file to check for embedded PE. - /// - public ulong MaxEmbeddedPE - { - get - { - return (ulong)EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_EMBEDDEDPE); - } - set - { - EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_EMBEDDEDPE, (long)value); - } - } - - /// - /// Maximum size of HTML file to normalize. - /// - public ulong MaxHtmlNormalize - { - get - { - return (ulong)EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_HTMLNORMALIZE); - } - set - { - EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_HTMLNORMALIZE, (long)value); - } - } - - /// - /// Maximum size of normalized HTML file to scan. - /// - public ulong MaxHtmlNoTags - { - get - { - return (ulong)EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_HTMLNOTAGS); - } - set - { - EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_HTMLNOTAGS, (long)value); - } - } - - /// - /// Maximum size of script file to normalize. - /// - public ulong MaxScriptNormalize - { - get - { - return (ulong)EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_SCRIPTNORMALIZE); - } - set - { - EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_SCRIPTNORMALIZE, (long)value); - } - } - - /// - /// Maximum size zip to type reanalyze. - /// - public ulong MaxZipTypeRcg - { - get - { - return (ulong)EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_ZIPTYPERCG); - } - set - { - EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_ZIPTYPERCG, (long)value); - } - } - - /// - /// This option causes memory or nested map scans to dump the content to disk. - /// - public bool ForceToDisk - { - get - { - return EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_FORCETODISK) != 0; - } - set - { - EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_FORCETODISK, value ? 1 : 0); - } - } - - /// - /// This option allows you to disable the caching feature of the engine. By - /// default, the engine will store an MD5 in a cache of any files that are - /// not flagged as virus or that hit limits checks. Disabling the cache will - /// have a negative performance impact on large scans. - /// - public bool DisableCache - { - get - { - return EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_DISABLE_CACHE) != 0; - } - set - { - EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_DISABLE_CACHE, value ? 1 : 0); - } - } - - /// - /// Disable submission of PE section statistical data. - /// - public bool DisablePeStats - { - get - { - return EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_DISABLE_PE_STATS) != 0; - } - set - { - EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_DISABLE_PE_STATS, value ? 1 : 0); - } - } - - /// - /// Timeout in seconds to timeout communication with the stats server. - /// - public uint StatsTimeout - { - get - { - return (uint)EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_STATS_TIMEOUT); - } - set - { - EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_STATS_TIMEOUT, (long)value); - } - } - - /// - /// This option sets the maximum number of partitions of a raw disk image to be scanned. - /// Raw disk images with more partitions than this value will have up to the value number partitions scanned. - /// Negative values are not allowed. - /// - /// WARNING: setting this limit too high may result in severe damage or impact performance. - /// - public uint MaxPartitions - { - get - { - return (uint)EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_PARTITIONS); - } - set - { - EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_PARTITIONS, (long)value); - } - } - - /// - /// This option sets the maximum number of icons within a PE to be scanned. - /// PE files with more icons than this value will have up to the value number icons scanned. - /// Negative values are not allowed. - /// - /// WARNING: setting this limit too high may result in severe damage or impact performance. - /// - public uint MaxIconSpe - { - get - { - return (uint)EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_ICONSPE); - } - set - { - EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_ICONSPE, value); - } - } - - /// - /// This option sets the maximum recursive calls to HWP3 parsing function. - /// HWP3 files using more than this limit will be terminated and alert the user. - /// Scans will be unable to scan any HWP3 attachments if the recursive limit is reached. - /// Negative values are not allowed. - /// - /// WARNING: setting this limit too high may result in severe damage or impact performance. - /// - public uint MaxRecHwp3 - { - get - { - return (uint)EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_RECHWP3); - } - set - { - EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_RECHWP3, value); - } - } - - /// - /// This clamscan option is currently for testing only. It sets the engine parameter CL_ENGINE_TIME_LIMIT. The value is in milliseconds. - /// - public uint TimeLimit - { - get - { - return (uint)EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_TIME_LIMIT); - } - set - { - EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_TIME_LIMIT, value); - } - } - - /// - /// This option sets the maximum calls to the PCRE match function during an instance of regex matching. - /// Instances using more than this limit will be terminated and alert the user but the scan will continue. - /// For more information on match_limit, see the PCRE documentation. - /// - /// Negative values are not allowed. - /// - /// WARNING: setting this limit too high may severely impact performance. - /// - public ulong PcreMatchLimit - { - get - { - return (ulong)EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_PCRE_MATCH_LIMIT); - } - set - { - EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_PCRE_MATCH_LIMIT, (long)value); - } - } - - /// - /// This option sets the maximum recursive calls to the PCRE match function during an instance of regex matching. - /// Instances using more than this limit will be terminated and alert the user but the scan will continue. - /// For more information on match_limit_recursion, see the PCRE documentation. - /// Negative values are not allowed and values > PCREMatchLimit are superfluous. - /// - /// WARNING: setting this limit too high may severely impact performance. - /// - public ulong PcreRecMatchLimit - { - get - { - return (ulong)EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_PCRE_RECMATCH_LIMIT); - } - set - { - EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_PCRE_RECMATCH_LIMIT, (long)value); - } - } - - /// - /// - /// - public ulong PcreMaxFilesize - { - get - { - return (ulong)EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_PCRE_MAX_FILESIZE); - } - set - { - EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_MAX_FILESIZE, (long)value); - } - } - - /// - /// - /// - public bool DisablePeCerts - { - get - { - return EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_DISABLE_PE_CERTS) != 0; - } - set - { - EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_DISABLE_PE_CERTS, value ? 1 : 0); - } - } - - /// - /// Dump PE certificates. - /// - public bool PeDumpCerts - { - get - { - return EngineGetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_PE_DUMPCERTS) != 0; - } - set - { - EngineSetNum(UnsafeNativeMethods.cl_engine_field.CL_ENGINE_PE_DUMPCERTS, value ? 1 : 0); - } - } + public string DatabaseDirectory => + _databaseDirectory ?? (_databaseDirectory = UnmarshalString(UnsafeNativeMethods.cl_retdbdir())); #endregion @@ -823,13 +175,12 @@ public void Dispose() /// Whether the dispose method has been called from the finalizer. protected virtual void Dispose(bool b) { - if (!_disposed && _engine.ToInt64() != 0) - { - // Free ClamAV engine instance. - int result = UnsafeNativeMethods.cl_engine_free(_engine); + if (_disposed || _engine.ToInt64() == 0) + return; - _disposed = true; - } + int result = UnsafeNativeMethods.cl_engine_free(_engine); + + _disposed = true; } #endregion