添加病毒扫描
This commit is contained in:
@@ -0,0 +1 @@
|
||||
# dummy
|
65
clamscan/libclamunrar_iface/CMakeLists.txt
Normal file
65
clamscan/libclamunrar_iface/CMakeLists.txt
Normal file
@@ -0,0 +1,65 @@
|
||||
|
||||
cmake_minimum_required( VERSION 3.13 )
|
||||
|
||||
if(WIN32)
|
||||
add_definitions(-DWIN32_LEAN_AND_MEAN)
|
||||
add_definitions(-DHAVE_STRUCT_TIMESPEC)
|
||||
|
||||
# Windows compatibility headers
|
||||
include_directories(${CMAKE_SOURCE_DIR}/win32/compat)
|
||||
endif()
|
||||
|
||||
# Move public headers to a dedicated INTERFACE library
|
||||
#
|
||||
# An interface is required because libclamav objects will depend on the
|
||||
# interface to put unrar_iface.h in the include path, but we don't want to link
|
||||
# with it.
|
||||
# libclamunrar_iface will be dynamically loaded at run time, if enabled.
|
||||
add_library(clamunrar_iface_iface INTERFACE)
|
||||
target_sources(clamunrar_iface_iface
|
||||
INTERFACE
|
||||
unrar_iface.h )
|
||||
target_include_directories( clamunrar_iface_iface
|
||||
INTERFACE
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> )
|
||||
|
||||
add_library( ClamAV::libclamunrar_iface_iface ALIAS clamunrar_iface_iface )
|
||||
|
||||
if(ENABLE_UNRAR)
|
||||
# The clamunrar_iface SHARED library.
|
||||
add_library( clamunrar_iface SHARED )
|
||||
set_target_properties(clamunrar_iface PROPERTIES
|
||||
VERSION ${LIBCLAMAV_VERSION}
|
||||
SOVERSION ${LIBCLAMAV_SOVERSION})
|
||||
target_sources( clamunrar_iface
|
||||
PRIVATE
|
||||
unrar_iface.cpp )
|
||||
|
||||
target_include_directories( clamunrar_iface
|
||||
PRIVATE
|
||||
"${CMAKE_BINARY_DIR}" # For clamav-config.h
|
||||
$<TARGET_PROPERTY:ClamAV::libclamunrar,INTERFACE_INCLUDE_DIRECTORIES>
|
||||
$<TARGET_PROPERTY:ClamAV::libclamav,INTERFACE_INCLUDE_DIRECTORIES> )
|
||||
|
||||
set_target_properties( clamunrar_iface PROPERTIES
|
||||
COMPILE_FLAGS "${WARNCXXFLAGS} ${CXX1XCXXFLAGS}" )
|
||||
|
||||
if(WIN32)
|
||||
set_target_properties(clamunrar_iface PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
||||
endif()
|
||||
|
||||
# Private (internal-only) dependencies.
|
||||
target_link_libraries( clamunrar_iface
|
||||
PRIVATE
|
||||
ClamAV::libclamunrar
|
||||
PUBLIC
|
||||
ClamAV::libclamunrar_iface_iface)
|
||||
|
||||
if(WIN32)
|
||||
install(TARGETS clamunrar_iface DESTINATION ${CMAKE_INSTALL_PREFIX})
|
||||
else()
|
||||
install(TARGETS clamunrar_iface DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
endif()
|
||||
|
||||
add_library( ClamAV::libclamunrar_iface ALIAS clamunrar_iface )
|
||||
endif()
|
22
clamscan/libclamunrar_iface/Doxyfile
Normal file
22
clamscan/libclamunrar_iface/Doxyfile
Normal file
@@ -0,0 +1,22 @@
|
||||
PROJECT_NAME = ClamAV - Libclamunrar_iface
|
||||
OUTPUT_DIRECTORY = ../docs/libclamunrar_iface
|
||||
WARNINGS = YES
|
||||
FILE_PATTERNS = *.c *.h
|
||||
PERL_PATH = /usr/bin/perl
|
||||
SEARCHENGINE = YES
|
||||
|
||||
GENERATE_LATEX=NO
|
||||
OPTIMIZE_OUTPUT_FOR_C=YES
|
||||
HAVE_DOT=YES
|
||||
CALL_GRAPH=YES
|
||||
CALLER_GRAPH=YES
|
||||
JAVADOC_AUTOBRIEF=YES
|
||||
GENERATE_MAN=NO
|
||||
EXAMPLE_PATH=examples
|
||||
|
||||
DOT_CLEANUP=NO
|
||||
MAX_DOT_GRAPH_DEPTH=3
|
||||
|
||||
EXTRACT_ALL=YES
|
||||
INPUT = . \
|
||||
../shared
|
10
clamscan/libclamunrar_iface/libclamunrar_iface.map
Normal file
10
clamscan/libclamunrar_iface/libclamunrar_iface.map
Normal file
@@ -0,0 +1,10 @@
|
||||
CLAMAV_PRIVATE {
|
||||
global:
|
||||
libclamunrar_iface_LTX_unrar_open;
|
||||
libclamunrar_iface_LTX_unrar_peek_file_header;
|
||||
libclamunrar_iface_LTX_unrar_extract_file;
|
||||
libclamunrar_iface_LTX_unrar_skip_file;
|
||||
libclamunrar_iface_LTX_unrar_close;
|
||||
local:
|
||||
*;
|
||||
};
|
490
clamscan/libclamunrar_iface/unrar_iface.cpp
Normal file
490
clamscan/libclamunrar_iface/unrar_iface.cpp
Normal file
@@ -0,0 +1,490 @@
|
||||
/*
|
||||
* Interface to libclamunrar
|
||||
*
|
||||
* Copyright (C) 2013-2022 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
|
||||
* Copyright (C) 2007-2013 Sourcefire, Inc.
|
||||
*
|
||||
* Authors: Trog, Torok Edvin, Tomasz Kojm, Micah Snyder
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "rar.hpp"
|
||||
#include "dll.hpp"
|
||||
|
||||
extern "C" {
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <wchar.h>
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "unrar_iface.h"
|
||||
#include "clamav-types.h"
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(x, y) ((x) < (y) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(x, y) ((x) > (y) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
/* tell compiler about branches that are very rarely taken,
|
||||
* such as debug paths, and error paths */
|
||||
#if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 2)
|
||||
#define UNLIKELY(cond) __builtin_expect(!!(cond), 0)
|
||||
#define LIKELY(cond) __builtin_expect(!!(cond), 1)
|
||||
#else
|
||||
#define UNLIKELY(cond) (cond)
|
||||
#define LIKELY(cond) (cond)
|
||||
#endif
|
||||
|
||||
#define unrar_dbgmsg (!UNLIKELY(unrar_debug)) ? (void)0 : unrar_dbgmsg_internal
|
||||
|
||||
#define CMTBUFSIZE (64 * 1024)
|
||||
|
||||
int CALLBACK CallbackProc(UINT msg, LPARAM UserData, LPARAM P1, LPARAM P2);
|
||||
|
||||
static void unrar_dbgmsg_internal(const char* str, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, str);
|
||||
vfprintf(stderr, str, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
uint8_t unrar_debug = 0;
|
||||
|
||||
/**
|
||||
* @brief Translate an ERAR_<code> to the appropriate UNRAR_<code>
|
||||
*
|
||||
* @param errorCode ERAR_<code>
|
||||
* @return cl_unrar_error_t UNRAR_OK, UNRAR_ENCRYPTED, or UNRAR_ERR.
|
||||
*/
|
||||
static cl_unrar_error_t unrar_retcode(int retcode)
|
||||
{
|
||||
cl_unrar_error_t status = UNRAR_ERR;
|
||||
|
||||
switch (retcode) {
|
||||
case ERAR_SUCCESS: {
|
||||
unrar_dbgmsg("unrar_retcode: Success!\n");
|
||||
status = UNRAR_OK;
|
||||
break;
|
||||
}
|
||||
case ERAR_END_ARCHIVE: {
|
||||
unrar_dbgmsg("unrar_retcode: No more files in archive.\n");
|
||||
status = UNRAR_BREAK;
|
||||
break;
|
||||
}
|
||||
case ERAR_NO_MEMORY: {
|
||||
unrar_dbgmsg("unrar_retcode: Not enough memory!\n");
|
||||
status = UNRAR_EMEM;
|
||||
break;
|
||||
}
|
||||
case ERAR_MISSING_PASSWORD: {
|
||||
unrar_dbgmsg("unrar_retcode: Encrypted file header found in archive.\n");
|
||||
status = UNRAR_ENCRYPTED;
|
||||
break;
|
||||
}
|
||||
case ERAR_BAD_PASSWORD: {
|
||||
unrar_dbgmsg("unrar_retcode: Encrypted archive or encrypted file in archive.\n");
|
||||
status = UNRAR_ENCRYPTED;
|
||||
break;
|
||||
}
|
||||
case ERAR_BAD_DATA: {
|
||||
unrar_dbgmsg("unrar_retcode: Bad data / File CRC error.\n");
|
||||
break;
|
||||
}
|
||||
case ERAR_UNKNOWN_FORMAT: {
|
||||
unrar_dbgmsg("unrar_retcode: Unknown archive format.\n");
|
||||
break;
|
||||
}
|
||||
case ERAR_EOPEN: {
|
||||
unrar_dbgmsg("unrar_retcode: Volume open error.\n");
|
||||
status = UNRAR_EOPEN;
|
||||
break;
|
||||
}
|
||||
case ERAR_ECREATE: {
|
||||
unrar_dbgmsg("unrar_retcode: File create error.\n");
|
||||
break;
|
||||
}
|
||||
case ERAR_ECLOSE: {
|
||||
unrar_dbgmsg("unrar_retcode: File close error.\n");
|
||||
break;
|
||||
}
|
||||
case ERAR_EREAD: {
|
||||
unrar_dbgmsg("unrar_retcode: Read error.\n");
|
||||
break;
|
||||
}
|
||||
case ERAR_EWRITE: {
|
||||
unrar_dbgmsg("unrar_retcode: Write error.\n");
|
||||
break;
|
||||
}
|
||||
case ERAR_EREFERENCE: {
|
||||
unrar_dbgmsg("unrar_retcode: Error attempting to unpack the reference record without its source file.\n");
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
unrar_dbgmsg("unrar_retcode: Unexpected error code: %d\n", retcode);
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
static size_t unrar_strnlen(const char* s, size_t n)
|
||||
{
|
||||
size_t i = 0;
|
||||
for (; (i < n) && s[i] != '\0'; ++i)
|
||||
;
|
||||
return i;
|
||||
}
|
||||
|
||||
static char* unrar_strndup(const char* s, size_t n)
|
||||
{
|
||||
char* alloc;
|
||||
size_t len;
|
||||
|
||||
if (!s) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
len = unrar_strnlen(s, n);
|
||||
alloc = (char*)malloc(len + 1);
|
||||
|
||||
if (!alloc) {
|
||||
return NULL;
|
||||
} else
|
||||
memcpy(alloc, s, len);
|
||||
|
||||
alloc[len] = '\0';
|
||||
return alloc;
|
||||
}
|
||||
|
||||
cl_unrar_error_t unrar_open(const char* filename, void** hArchive, char** comment, uint32_t* comment_size, uint8_t debug_flag)
|
||||
{
|
||||
struct RAROpenArchiveDataEx* archiveData = NULL;
|
||||
HANDLE archiveHandle = NULL;
|
||||
cl_unrar_error_t status = UNRAR_ERR;
|
||||
|
||||
if (NULL == filename || NULL == hArchive || NULL == comment || NULL == comment_size) {
|
||||
unrar_dbgmsg("unrar_open: Invalid arguments.\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Enable debug messages in unrar_iface.cpp */
|
||||
unrar_debug = debug_flag;
|
||||
|
||||
archiveData = (struct RAROpenArchiveDataEx*)calloc(sizeof(struct RAROpenArchiveDataEx), 1);
|
||||
if (archiveData == NULL) {
|
||||
unrar_dbgmsg("unrar_open: Not enough memory to allocate main archive header data structure.\n");
|
||||
status = UNRAR_EMEM;
|
||||
}
|
||||
archiveData->ArcName = (char*)filename;
|
||||
archiveData->OpenMode = RAR_OM_EXTRACT;
|
||||
archiveData->OpFlags |= ROADOF_KEEPBROKEN;
|
||||
archiveData->CmtBuf = (char*)calloc(1, CMTBUFSIZE);
|
||||
if (archiveData->CmtBuf == NULL) {
|
||||
unrar_dbgmsg("unrar_open: Not enough memory to allocate main archive header comment buffer.\n");
|
||||
status = UNRAR_EMEM;
|
||||
}
|
||||
archiveData->CmtBufSize = CMTBUFSIZE;
|
||||
|
||||
if (NULL == (archiveHandle = RAROpenArchiveEx(archiveData))) {
|
||||
/* Failed to open archive */
|
||||
unrar_dbgmsg("unrar_open: Failed to open archive: %s\n", filename);
|
||||
status = unrar_retcode(archiveData->OpenResult);
|
||||
goto done;
|
||||
}
|
||||
|
||||
switch (archiveData->CmtState) {
|
||||
case 0: {
|
||||
unrar_dbgmsg("unrar_open: Comments are not present in this archive.\n");
|
||||
break;
|
||||
}
|
||||
case ERAR_BAD_DATA: {
|
||||
unrar_dbgmsg("unrar_open: Archive Comments may be broken.\n");
|
||||
}
|
||||
case ERAR_SMALL_BUF: {
|
||||
unrar_dbgmsg("unrar_open: Archive Comments are not present in this file.\n");
|
||||
}
|
||||
case 1: {
|
||||
unrar_dbgmsg("unrar_open: Archive Comments:\n\t %s\n", archiveData->CmtBuf);
|
||||
break;
|
||||
}
|
||||
case ERAR_NO_MEMORY: {
|
||||
unrar_dbgmsg("unrar_open: Memory error when reading archive comments!\n");
|
||||
status = UNRAR_EMEM;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
unrar_dbgmsg("unrar_open: Unknown archive comment state %u!\n", archiveData->CmtState);
|
||||
}
|
||||
}
|
||||
|
||||
if (archiveData->CmtSize > 0) {
|
||||
*comment_size = MIN(archiveData->CmtSize, archiveData->CmtBufSize);
|
||||
*comment = unrar_strndup(archiveData->CmtBuf, *comment_size);
|
||||
if (NULL == *comment) {
|
||||
unrar_dbgmsg("unrar_open: Error duplicating comment buffer.\n");
|
||||
*comment_size = 0;
|
||||
status = UNRAR_EMEM;
|
||||
}
|
||||
}
|
||||
|
||||
unrar_dbgmsg("unrar_open: Volume attribute (archive volume): %s\n", (archiveData->Flags & ROADF_VOLUME) ? "yes" : "no");
|
||||
unrar_dbgmsg("unrar_open: Archive comment present: %s\n", (archiveData->Flags & ROADF_COMMENT) ? "yes" : "no");
|
||||
unrar_dbgmsg("unrar_open: Archive lock attribute: %s\n", (archiveData->Flags & ROADF_LOCK) ? "yes" : "no");
|
||||
unrar_dbgmsg("unrar_open: Solid attribute (solid archive): %s\n", (archiveData->Flags & ROADF_SOLID) ? "yes" : "no");
|
||||
unrar_dbgmsg("unrar_open: New volume naming scheme ('volname.partN.rar'): %s\n", (archiveData->Flags & ROADF_NEWNUMBERING) ? "yes" : "no");
|
||||
unrar_dbgmsg("unrar_open: Authenticity information present (obsolete): %s\n", (archiveData->Flags & ROADF_SIGNED) ? "yes" : "no");
|
||||
unrar_dbgmsg("unrar_open: Recovery record present: %s\n", (archiveData->Flags & ROADF_RECOVERY) ? "yes" : "no");
|
||||
unrar_dbgmsg("unrar_open: Block headers are encrypted: %s\n", (archiveData->Flags & ROADF_ENCHEADERS) ? "yes" : "no");
|
||||
unrar_dbgmsg("unrar_open: First volume (set only by RAR 3.0 and later): %s\n", (archiveData->Flags & ROADF_FIRSTVOLUME) ? "yes" : "no");
|
||||
|
||||
unrar_dbgmsg("unrar_open: Opened archive: %s\n", filename);
|
||||
*hArchive = (void*)archiveHandle;
|
||||
status = UNRAR_OK;
|
||||
|
||||
done:
|
||||
|
||||
if (NULL != archiveData) {
|
||||
if (NULL != archiveData->CmtBuf) {
|
||||
free(archiveData->CmtBuf);
|
||||
archiveData->CmtBuf = NULL;
|
||||
}
|
||||
free(archiveData);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get file metadata from the next file header.
|
||||
*
|
||||
* @param hArchive Handle to the archive we're extracting.
|
||||
* @param[in/out] file_metadata Pointer to a pre-allocated metadata structure.
|
||||
* @return cl_unrar_error_t UNRAR_OK if metadata retrieved, UNRAR_BREAK if no more files, UNRAR_ENCRYPTED if header was encrypted, else maybe UNRAR_EMEM or UNRAR_ERR.
|
||||
*/
|
||||
cl_unrar_error_t unrar_peek_file_header(void* hArchive, unrar_metadata_t* file_metadata)
|
||||
{
|
||||
cl_unrar_error_t status = UNRAR_ERR;
|
||||
|
||||
struct RARHeaderDataEx headerData;
|
||||
int read_header_ret = 0;
|
||||
|
||||
wchar_t RedirName[1024];
|
||||
|
||||
memset(&headerData, 0, sizeof(struct RARHeaderDataEx));
|
||||
|
||||
if (NULL == hArchive || NULL == file_metadata) {
|
||||
unrar_dbgmsg("unrar_peek_file_header: Invalid arguments.\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
memset(file_metadata, 0, sizeof(unrar_metadata_t));
|
||||
|
||||
/*
|
||||
* File header comments are not functional in unrar 5.6.5 and the struct member only exists for backwards compatibility.
|
||||
* The unrar user manual says to set headerData.CmtBuff = NULL, and headerData.CmtBufSize = 0.
|
||||
*/
|
||||
headerData.CmtBuf = NULL;
|
||||
headerData.CmtBufSize = 0;
|
||||
|
||||
headerData.RedirNameSize = 1024 * sizeof(wchar_t);
|
||||
headerData.RedirName = (wchar_t*)&RedirName;
|
||||
memset(headerData.RedirName, 0, headerData.RedirNameSize);
|
||||
|
||||
read_header_ret = RARReadHeaderEx(hArchive, &headerData);
|
||||
if (ERAR_SUCCESS != read_header_ret) {
|
||||
status = unrar_retcode(read_header_ret);
|
||||
goto done;
|
||||
}
|
||||
|
||||
file_metadata->unpack_size = headerData.UnpSize + ((int64_t)headerData.UnpSizeHigh << 32);
|
||||
file_metadata->pack_size = headerData.PackSize + ((int64_t)headerData.PackSizeHigh << 32);
|
||||
file_metadata->filename = unrar_strndup(headerData.FileName, 1024);
|
||||
file_metadata->crc = headerData.FileCRC;
|
||||
file_metadata->encrypted = (headerData.Flags & RHDF_ENCRYPTED) ? 1 : 0;
|
||||
file_metadata->is_dir = (headerData.Flags & RHDF_DIRECTORY) ? 1 : 0;
|
||||
file_metadata->method = headerData.Method;
|
||||
|
||||
unrar_dbgmsg("unrar_peek_file_header: Name: %s\n", headerData.FileName);
|
||||
unrar_dbgmsg("unrar_peek_file_header: Directory?: %u\n", file_metadata->is_dir);
|
||||
unrar_dbgmsg("unrar_peek_file_header: Target Dir: %u\n", headerData.DirTarget);
|
||||
unrar_dbgmsg("unrar_peek_file_header: RAR Version: %u\n", headerData.UnpVer);
|
||||
unrar_dbgmsg("unrar_peek_file_header: Packed Size: %" PRIu64 "\n", file_metadata->pack_size);
|
||||
unrar_dbgmsg("unrar_peek_file_header: Unpacked Size: %" PRIu64 "\n", file_metadata->unpack_size);
|
||||
|
||||
// PrintTime("mtime",HeaderData.MtimeLow,HeaderData.MtimeHigh);
|
||||
// PrintTime("ctime",HeaderData.CtimeLow,HeaderData.CtimeHigh);
|
||||
// PrintTime("atime",HeaderData.AtimeLow,HeaderData.AtimeHigh);
|
||||
|
||||
if (headerData.RedirType != 0) {
|
||||
unrar_dbgmsg("unrar_peek_file_header: link type %d, target %ls\n", headerData.RedirType, headerData.RedirName);
|
||||
}
|
||||
|
||||
status = UNRAR_OK;
|
||||
|
||||
done:
|
||||
|
||||
if (NULL != headerData.CmtBuf) {
|
||||
free(headerData.CmtBuf);
|
||||
headerData.CmtBuf = NULL;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
cl_unrar_error_t unrar_extract_file(void* hArchive, const char* destPath, char* outputBuffer)
|
||||
{
|
||||
cl_unrar_error_t status = UNRAR_ERR;
|
||||
int process_file_ret = 0;
|
||||
|
||||
if (NULL == hArchive || NULL == destPath) {
|
||||
unrar_dbgmsg("unrar_extract_file: Invalid arguments.\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (NULL != outputBuffer) {
|
||||
LPARAM UserData = (LPARAM)outputBuffer;
|
||||
RARSetCallback(hArchive, CallbackProc, UserData);
|
||||
}
|
||||
|
||||
process_file_ret = RARProcessFile(hArchive, RAR_EXTRACT, NULL, (char*)destPath);
|
||||
if (ERAR_BAD_DATA == process_file_ret) {
|
||||
unrar_dbgmsg("unrar_extract_file: Warning: Bad data/Invalid CRC. Attempting to scan anyways...\n");
|
||||
} else if (ERAR_SUCCESS != process_file_ret) {
|
||||
status = unrar_retcode(process_file_ret);
|
||||
goto done;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
unrar_dbgmsg("unrar_extract_file: Extracted file to: %s\n", destPath);
|
||||
#else
|
||||
unrar_dbgmsg("unrar_extract_file: Extracted file to: %s\n", destPath);
|
||||
#endif
|
||||
|
||||
status = UNRAR_OK;
|
||||
|
||||
done:
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
cl_unrar_error_t unrar_skip_file(void* hArchive)
|
||||
{
|
||||
cl_unrar_error_t status = UNRAR_ERR;
|
||||
int process_file_ret = 0;
|
||||
|
||||
if (NULL == hArchive) {
|
||||
unrar_dbgmsg("unrar_skip_file: Invalid arguments.\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
process_file_ret = RARProcessFile(hArchive, RAR_SKIP, NULL, NULL);
|
||||
if (ERAR_SUCCESS != process_file_ret) {
|
||||
status = unrar_retcode(process_file_ret);
|
||||
goto done;
|
||||
}
|
||||
|
||||
unrar_dbgmsg("unrar_skip_file: File skipped.\n");
|
||||
|
||||
status = UNRAR_OK;
|
||||
|
||||
done:
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void unrar_close(void* hArchive)
|
||||
{
|
||||
RARCloseArchive(hArchive);
|
||||
}
|
||||
|
||||
int CALLBACK CallbackProc(UINT msg, LPARAM UserData, LPARAM P1, LPARAM P2)
|
||||
{
|
||||
int status = 1; /* -1 to cancel, 1 to continue */
|
||||
|
||||
switch (msg) {
|
||||
case UCM_CHANGEVOLUMEW: {
|
||||
/* We don't support RAR's split into multiple volumes
|
||||
* ClamAV is not aware of more than 1 file at a time */
|
||||
status = -1;
|
||||
unrar_dbgmsg("CallbackProc: Archive has multiple volumes, but we don't support multiple volumes.\n");
|
||||
break;
|
||||
}
|
||||
case UCM_PROCESSDATA: {
|
||||
char* UserBuffer = (char*)UserData;
|
||||
|
||||
if (UserBuffer == NULL) {
|
||||
/* No buffer provided, continue with extraction to a temp file. */
|
||||
status = 1;
|
||||
unrar_dbgmsg("CallbackProc: Extracting to a new tempfile!\n");
|
||||
} else {
|
||||
/* Buffer provided, write to it and cancel extraction to the temp file. */
|
||||
memcpy(UserBuffer, (char*)P1, P2);
|
||||
|
||||
status = -1;
|
||||
unrar_dbgmsg("CallbackProc: Extracting %lu bytes of data to a provided buffer.\n", P2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case UCM_NEEDPASSWORDW: {
|
||||
/* Let's try an empty password. Probably won't work. */
|
||||
wchar_t* password_buffer = (wchar_t*)P1;
|
||||
|
||||
if (NULL == password_buffer || P2 == 0) {
|
||||
status = -1;
|
||||
unrar_dbgmsg("CallbackProc: P1 callback argument is invalid.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
memset(password_buffer, 0, P2 * sizeof(wchar_t));
|
||||
|
||||
status = 1;
|
||||
unrar_dbgmsg("CallbackProc: Password required, attempting empty password.\n");
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
/* ... */
|
||||
unrar_dbgmsg("CallbackProc: Unexpected callback type!\n");
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
} /* extern "C" */
|
73
clamscan/libclamunrar_iface/unrar_iface.h
Normal file
73
clamscan/libclamunrar_iface/unrar_iface.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Interface to libclamunrar
|
||||
*
|
||||
* Copyright (C) 2013-2022 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
|
||||
* Copyright (C) 2007-2013 Sourcefire, Inc.
|
||||
*
|
||||
* Authors: Trog, Torok Edvin, Tomasz Kojm, Micah Snyder
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __UNRAR_IFACE_H
|
||||
#define __UNRAR_IFACE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#define unrar_open libclamunrar_iface_LTX_unrar_open
|
||||
#define unrar_peek_file_header libclamunrar_iface_LTX_unrar_peek_file_header
|
||||
#define unrar_extract_file libclamunrar_iface_LTX_unrar_extract_file
|
||||
#define unrar_skip_file libclamunrar_iface_LTX_unrar_skip_file
|
||||
#define unrar_close libclamunrar_iface_LTX_unrar_close
|
||||
|
||||
typedef enum cl_unrar_error_tag {
|
||||
UNRAR_OK = 0,
|
||||
UNRAR_BREAK,
|
||||
UNRAR_ENCRYPTED,
|
||||
UNRAR_EMEM,
|
||||
UNRAR_ERR,
|
||||
UNRAR_EOPEN
|
||||
} cl_unrar_error_t;
|
||||
|
||||
typedef struct unrar_metadata_tag {
|
||||
uint64_t pack_size;
|
||||
uint64_t unpack_size;
|
||||
char *filename;
|
||||
uint32_t crc;
|
||||
unsigned int encrypted;
|
||||
uint8_t method;
|
||||
uint32_t is_dir;
|
||||
} unrar_metadata_t;
|
||||
|
||||
cl_unrar_error_t unrar_open(const char *filename, void **hArchive, char **comment, uint32_t *comment_size, uint8_t debug_flag);
|
||||
cl_unrar_error_t unrar_peek_file_header(void *hArchive, unrar_metadata_t *file_metadata);
|
||||
cl_unrar_error_t unrar_extract_file(void *hArchive, const char *destPath, char *outputBuffer);
|
||||
cl_unrar_error_t unrar_skip_file(void *hArchive);
|
||||
void unrar_close(void *hArchive);
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user