diff --git a/trunk/CMakeLists.txt b/trunk/CMakeLists.txt index 51f0066..3be1d84 100644 --- a/trunk/CMakeLists.txt +++ b/trunk/CMakeLists.txt @@ -1,77 +1,81 @@ cmake_minimum_required(VERSION 2.8) +project(xmount C) include(CheckIncludeFiles) #include(CheckCSourceCompiles) # Make sure CMAKE_BUILD_TYPE is set if(CMAKE_BUILD_TYPE STREQUAL "") set(CMAKE_BUILD_TYPE "Release") else(CMAKE_BUILD_TYPE STREQUAL "") - if(NOT (CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "Debug")) + if(NOT (CMAKE_BUILD_TYPE STREQUAL "Release" OR + CMAKE_BUILD_TYPE STREQUAL "Debug")) message(FATAL_ERROR "Only build types 'Release' and 'Debug' are supported!") - endif(NOT (CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "Debug")) + endif(NOT (CMAKE_BUILD_TYPE STREQUAL "Release" OR + CMAKE_BUILD_TYPE STREQUAL "Debug")) endif(CMAKE_BUILD_TYPE STREQUAL "") # Add cmake_modules dir to CMAKE_MODULE_PATH set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake_modules/") # Check required headers check_include_files(stdlib.h HAVE_STDLIB_H) check_include_files(stdio.h HAVE_STDIO_H) check_include_files(stdint.h HAVE_STDINT_H) check_include_files(stdarg.h HAVE_STDARG_H) check_include_files(string.h HAVE_STRING_H) check_include_files(errno.h HAVE_ERRNO_H) +check_include_files(fcntl.h HAVE_FCNTL_H) check_include_files(dlfcn.h HAVE_DLFCN_H) check_include_files(dirent.h HAVE_DIRENT_H) check_include_files(unistd.h HAVE_UNISTD_H) check_include_files(sys/ioctl.h HAVE_SYS_IOCTL_H) check_include_files(sys/types.h HAVE_SYS_TYPES_H) check_include_files(linux/fs.h HAVE_LINUX_FS_H) check_include_files(pthread.h HAVE_PTHREAD_H) check_include_files(time.h HAVE_TIME_H) check_include_files(inttypes.h HAVE_INTTYPES_H) check_include_files(byteswap.h HAVE_BYTESWAP_H) check_include_files(endian.h HAVE_ENDIAN_H) check_include_files(libkern/OSByteOrder.h HAVE_LIBKERN_OSBYTEORDER_H) # Check for required libs if(NOT APPLE) find_package(LibFUSE REQUIRED) include_directories(${LIBFUSE_INCLUDE_DIRS}) set(LIBS ${LIBS} ${LIBFUSE_LIBRARIES}) else(NOT APPLE) find_package(LibOSXFUSE REQUIRED) include_directories(${LIBOSXFUSE_INCLUDE_DIRS}) set(LIBS ${LIBS} ${LIBOSXFUSE_LIBRARIES}) endif(NOT APPLE) # Generate config.h and add it's path to the include dirs configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h) include_directories(${CMAKE_CURRENT_BINARY_DIR}) # Add preprocessor definitions add_definitions(-D_LARGEFILE64_SOURCE) add_definitions(-D_FILE_OFFSET_BITS=64) add_definitions(-D_GNU_SOURCE) set(CMAKE_C_FLAGS "-fno-strict-aliasing -std=c99 -Wall") set(CMAKE_C_FLAGS_RELEASE "-O2 ${CMAKE_C_FLAGS}") set(CMAKE_C_FLAGS_DEBUG "-ggdb -O0 ${CMAKE_C_FLAGS}") # Check that off_t can represent 2**63 - 1 correctly. # If it can't, we need to set _FILE_OFFSET_BITS=64 #check_c_source_compiles(" # #include # #define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) # int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 && LARGE_OFF_T % 2147483647 == 1) ? 1 : -1]; # int main() { return 0; } #" _OFFT_IS_64BIT) #if(NOT ${_OFFT_IS_64BIT}) # set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} "-D_FILE_OFFSET_BITS=64") #endif(NOT ${_OFFT_IS_64BIT}) # Compile stuff in sub dirs add_subdirectory(libxmount_input) add_subdirectory(src) diff --git a/trunk/cmake_modules/FindLibFUSE.cmake b/trunk/cmake_modules/FindLibFUSE.cmake index 0ec355b..22c6e55 100644 --- a/trunk/cmake_modules/FindLibFUSE.cmake +++ b/trunk/cmake_modules/FindLibFUSE.cmake @@ -1,20 +1,22 @@ find_package(PkgConfig) pkg_check_modules(PC_LIBFUSE QUIET libfuse) set(LIBFUSE_DEFINITIONS ${PC_LIBFUSE_CFLAGS_OTHER}) find_path(LIBFUSE_INCLUDE_DIR fuse.h HINTS ${PC_LIBFUSE_INCLUDEDIR} ${PC_LIBFUSE_INCLUDE_DIRS} PATH_SUFFIXES fuse) find_library(LIBFUSE_LIBRARY NAMES fuse libfuse HINTS ${PC_LIBFUSE_LIBDIR} ${PC_LIBFUSE_LIBRARY_DIRS}) set(LIBFUSE_LIBRARIES ${LIBFUSE_LIBRARY}) set(LIBFUSE_INCLUDE_DIRS ${LIBFUSE_INCLUDE_DIR}) include(FindPackageHandleStandardArgs) -# handle the QUIETLY and REQUIRED arguments and set LIBXML2_FOUND to TRUE -# if all listed variables are TRUE -find_package_handle_standard_args(LibFUSE DEFAULT_MSG LIBFUSE_LIBRARY LIBFUSE_INCLUDE_DIR) +find_package_handle_standard_args(LibFUSE + DEFAULT_MSG + LIBFUSE_LIBRARY + LIBFUSE_INCLUDE_DIR) mark_as_advanced(LIBFUSE_INCLUDE_DIR LIBFUSE_LIBRARY) + diff --git a/trunk/cmake_modules/FindLibOSXFUSE.cmake b/trunk/cmake_modules/FindLibOSXFUSE.cmake index 5542fc0..39fc74f 100644 --- a/trunk/cmake_modules/FindLibOSXFUSE.cmake +++ b/trunk/cmake_modules/FindLibOSXFUSE.cmake @@ -1,21 +1,22 @@ find_package(PkgConfig) pkg_check_modules(PC_LIBOSXFUSE QUIET libosxfuse) set(LIBOSXFUSE_DEFINITIONS ${PC_LIBOSXFUSE_CFLAGS_OTHER}) find_path(LIBOSXFUSE_INCLUDE_DIR fuse.h HINTS ${PC_LIBOSXFUSE_INCLUDEDIR} ${PC_LIBOSXFUSE_INCLUDE_DIRS} PATH_SUFFIXES osxfuse) find_library(LIBOSXFUSE_LIBRARY NAMES osxfuse libosxfuse HINTS ${PC_LIBOSXFUSE_LIBDIR} ${PC_LIBOSXFUSE_LIBRARY_DIRS}) set(LIBOSXFUSE_LIBRARIES ${LIBOSXFUSE_LIBRARY}) set(LIBOSXFUSE_INCLUDE_DIRS ${LIBOSXFUSE_INCLUDE_DIR}) include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(LibOSXFUSE DEFAULT_MSG +find_package_handle_standard_args(LibOSXFUSE + DEFAULT_MSG LIBOSXFUSE_LIBRARY LIBOSXFUSE_INCLUDE_DIR) mark_as_advanced(LIBOSXFUSE_INCLUDE_DIR LIBOSXFUSE_LIBRARY) diff --git a/trunk/config.h.in b/trunk/config.h.in index 5cfb397..50a71c7 100644 --- a/trunk/config.h.in +++ b/trunk/config.h.in @@ -1,44 +1,45 @@ /******************************************************************************* * xmount Copyright (c) 2008-2014 by Gillen Daniel * * * * xmount is a small tool to "fuse mount" various harddisk image formats as dd, * * vdi, vhd or vmdk files and enable virtual write access to them. * * * * 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 3 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, see . * *******************************************************************************/ #ifndef CONFIG_H #define CONFIG_H #cmakedefine HAVE_STDLIB_H 1 #cmakedefine HAVE_STDIO_H 1 #cmakedefine HAVE_STDINT_H 1 #cmakedefine HAVE_STDARG_H 1 #cmakedefine HAVE_STRING_H 1 #cmakedefine HAVE_ERRNO_H 1 +#cmakedefine HAVE_FCNTL_H 1 #cmakedefine HAVE_DLFCN_H 1 #cmakedefine HAVE_DIRENT_H 1 #cmakedefine HAVE_UNISTD_H 1 #cmakedefine HAVE_SYS_IOCTL_H 1 #cmakedefine HAVE_SYS_TYPES_H 1 #cmakedefine HAVE_LINUX_FS_H 1 #cmakedefine HAVE_PTHREAD_H 1 #cmakedefine HAVE_TIME_H 1 #cmakedefine HAVE_INTTYPES_H 1 #cmakedefine HAVE_BYTESWAP_H 1 #cmakedefine HAVE_ENDIAN_H 1 #cmakedefine HAVE_LIBKERN_OSBYTEORDER_H 1 #endif // CONFIG_H diff --git a/trunk/debian/control b/trunk/debian/control index d1bc10d..606b20f 100644 --- a/trunk/debian/control +++ b/trunk/debian/control @@ -1,20 +1,20 @@ Source: xmount Section: unknown Priority: low Maintainer: Gillen Daniel -Build-Depends: debhelper (>= 5), cmake, libfuse-dev (>= 2.7.1-2~bpo40+1), zlib1g-dev, libewf-dev, libafflib-dev +Build-Depends: debhelper (>= 5), cmake, pkg-config, libfuse-dev (>= 2.7.1-2~bpo40+1), zlib1g-dev, libewf-dev, libafflib-dev, libssl-dev Standards-Version: 3.7.3 Package: xmount Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Description: Tool to crossmount between multiple input and output harddisk image files xmount allows you to convert on-the-fly between multiple input and output harddisk image types. xmount creates a virtual file system using FUSE (Filesystem in Userspace) that contains a virtual representation of the input image. The virtual representation can be in raw DD, VirtualBox's virtual disk file format or in VmWare's VMDK file format. Input images can be raw DD, EWF (Expert Witness Compression Format) or AFF (Advanced Forensic Format) files. In addition, xmount also supports virtual write access to the output files that is redirected to a cache file. This makes it possible to boot acquired harddisk images using QEMU, KVM, VirtualBox, VmWare or alike. diff --git a/trunk/libxmount_input/CMakeLists.txt b/trunk/libxmount_input/CMakeLists.txt index 4913660..85d2d33 100644 --- a/trunk/libxmount_input/CMakeLists.txt +++ b/trunk/libxmount_input/CMakeLists.txt @@ -1,18 +1,19 @@ -#add_subdirectory(libxmount_input_dd) +add_subdirectory(libxmount_input_dd) find_package(LibEWF) if(LIBEWF_FOUND) add_subdirectory(libxmount_input_ewf) endif(LIBEWF_FOUND) -#find_package(LibAFF) -#if(LIBAFF_FOUND) -# add_subdirectory(libxmount_input_aff) -#endif(LIBAFF_FOUND) +find_package(LibAFF) +find_package(OpenSSL) +if(LIBAFF_FOUND AND OPENSSL_FOUND) + add_subdirectory(libxmount_input_aff) +endif(LIBAFF_FOUND AND OPENSSL_FOUND) #find_package(LibZ) #if(LIBZ_FOUND) # add_subdirectory(libxmount_input_aewf) # add_subdirectory(libxmount_input_aaff) #endif(LIBZ_FOUND) diff --git a/trunk/libxmount_input/libxmount_input.h b/trunk/libxmount_input/libxmount_input.h index 6ac7dbd..a2d3164 100644 --- a/trunk/libxmount_input/libxmount_input.h +++ b/trunk/libxmount_input/libxmount_input.h @@ -1,204 +1,206 @@ /******************************************************************************* * xmount Copyright (c) 2008-2014 by Gillen Daniel * * * * 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 3 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, see . * *******************************************************************************/ #ifndef LIBXMOUNT_INPUT_H #define LIBXMOUNT_INPUT_H #define LIBXMOUNT_INPUT_API_VERSION 1 +#include + #include // For int*_t and uint*_t #include // For PRI* //! Structure containing pointers to the lib's functions typedef struct s_LibXmountInputFunctions { //! Function to initialize handle /*! * This function is called once to allow the lib to alloc any needed * structures before other functions that rely upon a valid handle are called * (for ex. OptionsParse or Open). * * \param pp_handle Pointer to store handle to * \return 0 on success or error code */ int (*CreateHandle)(void **pp_handle); //! Function to destroy handle /*! * In this function, any structures allocated with CreateHandle should be * freed. It is generally the last function called before unloading of lib * happens. * * By convention, after this function has been called, *pp_handle must be * NULL. * * \param pp_handle Pointer to store handle to * \return 0 on success or error code */ int (*DestroyHandle)(void **pp_handle); //! Function to open input image /*! * Opens the specified image for reading. * * \param pp_handle Pointer to store handle of opened image to * \param pp_filename_arr Array containing all specified input images * \param filename_arr_len Length of pp_filename_arr * \return 0 on success or error code */ int (*Open)(void **pp_handle, const char **pp_filename_arr, uint64_t filename_arr_len); //! Function to close an opened input image /*! * Closes the input image and frees any memory allocaed during opening but * does not invalidate the main handle. Further calls to for ex. Open must * be possible without first calling CreateHandle again! * * \param pp_handle Pointer to the handle of the opened image * \return 0 on success or error code */ int (*Close)(void **pp_handle); //! Function to get the input image's size /*! * Returns the real size of the input image. Real means the size of the * uncompressed or otherwise made available data contained inside the input * image. * * \param p_handle Handle to the opened image * \param p_size Pointer to store input image's size to * \return 0 on success or error code */ int (*Size)(void *p_handle, uint64_t *p_size); //! Function to read data from input image /*! * Reads count bytes at offset from input image and copies them into memory * starting at the address of p_buf. Memory is pre-allocated to as much bytes * as should be read. * * \param p_handle Handle to the opened image * \param offset Position at which to start reading * \param p_buf Buffer to store read data to * \param count Amount of bytes to read * \return 0 on success or error code */ int (*Read)(void *p_handle, uint64_t offset, char *p_buf, uint32_t count); //! Function to get a help message for any supported lib-specific options /*! * Calling this function should return a string containing help messages for * any supported lib-specific options. Every line of this text must be * prepended with 6 spaces. * * Returned string must be constant. It won't be freed! * * If there is no help text, this function must return NULL. * * \return Pointer to a null-terminated string containing the help text */ const char* (*OptionsHelp)(); //! Function to parse any lib-specific options /*! * This function is called with the options given with the --inopts parameter. * All contained options are for the lib. If errors or unknown options are * found, this function should fail and return an error message in pp_error. * pp_error will be freed by the caller by using FreeBuffer. * * \param p_handle Handle to the opened image * \param p_options String with specified options * \param pp_error Pointer to a string with error message * \return 0 on success or error code and error message */ int (*OptionsParse)(void *p_handle, char *p_options, char **pp_error); //! Function to get content to add to the info file /*! * The returned string is added to xmount's info file. This function is only * called once when the info file is generated. The returned string is then * freed with a call to FreeBuffer. * * \param p_handle Handle to the opened image * \param pp_info_buf Pointer to store the null-terminated content * \return 0 on success or error code */ int (*GetInfofileContent)(void *p_handle, char **pp_info_buf); //! Function to get an error message /*! * This function should translate an error code that was previously returned * by one of the library functions into a human readable error message. * * By convention, this function must always return a valid pointer to a * NULL-terminated string! * * \param err_num Error code as returned by lib */ const char* (*GetErrorMessage)(int err_num); //! Function to free buffers that were allocated by lib /*! * \param p_buf Buffer to free */ void (*FreeBuffer)(void *p_buf); } ts_LibXmountInputFunctions, *pts_LibXmountInputFunctions; //! Get library API version /*! * This function should return the value of LIBXMOUNT_INPUT_API_VERSION * * \return Supported version */ uint8_t LibXmount_Input_GetApiVersion(); typedef uint8_t (*t_LibXmount_Input_GetApiVersion)(); //! Get a list of supported formats /*! * Gets a list of supported input image formats. These are the strings * specified with xmount's --in command line option. The returned * string must be a constant list of image formats split by \0 chars. To mark * the end of the string, a single \0 must be used. * * As an example, "first\0second\0\0" would be a correct string to return for * a lib supporting two input image formats. * * \return List containing supported format strings */ const char* LibXmount_Input_GetSupportedFormats(); typedef const char* (*t_LibXmount_Input_GetSupportedFormats)(); //! Get the lib's s_LibXmountInputFunctions structure /*! * This function should set the members of the given s_LibXmountInputFunctions * structure to the internal lib functions. All members have to be set. * * \param p_functions s_LibXmountInputFunctions structure to fill */ void LibXmount_Input_GetFunctions(pts_LibXmountInputFunctions p_functions); typedef void (*t_LibXmount_Input_GetFunctions)(pts_LibXmountInputFunctions); #endif // LIBXMOUNT_INPUT_H diff --git a/trunk/libxmount_input/libxmount_input_aff/CMakeLists.txt b/trunk/libxmount_input/libxmount_input_aff/CMakeLists.txt index a9e9c4c..d948c51 100644 --- a/trunk/libxmount_input/libxmount_input_aff/CMakeLists.txt +++ b/trunk/libxmount_input/libxmount_input_aff/CMakeLists.txt @@ -1,9 +1,15 @@ -# TODO: https://www.mail-archive.com/cmake@cmake.org/msg32933.html +if(POLICY CMP0042) + cmake_policy(SET CMP0042 NEW) # CMake 3.0 +endif(POLICY CMP0042) + +project(libxmount_input_aff C) -cmake_minimum_required(VERSION 2.8) -project(libxmount_input_aff) add_library(xmount_input_aff SHARED libxmount_input_aff.c) -install(TARGETS xmount_input_aff DESTINATION lib/xmount) include_directories(${LIBAFF_INCLUDE_DIRS}) +include_directories(${OPENSSL_INCLUDE_DIRS}) set(LIBS ${LIBS} ${LIBAFF_LIBRARIES}) +set(LIBS ${LIBS} ${OPENSSL_LIBRARIES}) target_link_libraries(xmount_input_aff ${LIBS}) + +install(TARGETS xmount_input_aff DESTINATION lib/xmount) + diff --git a/trunk/libxmount_input/libxmount_input_aff/libxmount_input_aff.c b/trunk/libxmount_input/libxmount_input_aff/libxmount_input_aff.c index 45f32be..a92a923 100644 --- a/trunk/libxmount_input/libxmount_input_aff/libxmount_input_aff.c +++ b/trunk/libxmount_input/libxmount_input_aff/libxmount_input_aff.c @@ -1,196 +1,220 @@ /******************************************************************************* * xmount Copyright (c) 2008-2014 by Gillen Daniel * * * -* xmount is a small tool to "fuse mount" various image formats and enable * -* virtual write access. * -* * * 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 3 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, see . * *******************************************************************************/ #undef HAVE_LIBAFF_STATIC #include #include +#include // For O_RDONLY +// Need to include this header first as afflib.h uses uint*_t types without +// including correct header #include "../libxmount_input.h" #ifndef HAVE_LIBAFF_STATIC #include #else #include "libaff/lib/afflib.h" #endif -/******************************************************************************* - * Forward declarations - ******************************************************************************/ -int AffInitHandle(void **pp_handle); -int AffOpen(void **pp_handle, - const char **pp_filename_arr, - uint64_t filename_arr_len); -int AffSize(void *p_handle, - uint64_t *p_size); -int AffRead(void *p_handle, - uint64_t seek, - unsigned char *p_buf, - uint32_t count); -int AffClose(void **pp_handle); -const char* AffOptionsHelp(); -int AffOptionsParse(void *p_handle, - char *p_options, - char **pp_error); -int AffGetInfofileContent(void *p_handle, - const char **pp_info_buf); -void AffFreeBuffer(void *p_buf); +#include "libxmount_input_aff.h" /******************************************************************************* * LibXmount_Input API implementation ******************************************************************************/ /* * LibXmount_Input_GetApiVersion */ uint8_t LibXmount_Input_GetApiVersion() { return LIBXMOUNT_INPUT_API_VERSION; } /* * LibXmount_Input_GetSupportedFormats */ const char* LibXmount_Input_GetSupportedFormats() { return "aff\0\0"; } /* * LibXmount_Input_GetFunctions */ void LibXmount_Input_GetFunctions(ts_LibXmountInputFunctions *p_functions) { - p_functions->InitHandle=&AffInitHandle; + p_functions->CreateHandle=&AffCreateHandle; + p_functions->DestroyHandle=&AffDestroyHandle; p_functions->Open=&AffOpen; + p_functions->Close=&AffClose; p_functions->Size=&AffSize; p_functions->Read=&AffRead; - p_functions->Close=&AffClose; p_functions->OptionsHelp=&AffOptionsHelp; p_functions->OptionsParse=&AffOptionsParse; p_functions->GetInfofileContent=&AffGetInfofileContent; + p_functions->GetErrorMessage=&AffGetErrorMessage; p_functions->FreeBuffer=&AffFreeBuffer; } /******************************************************************************* * Private ******************************************************************************/ /* - * AffInitHandle + * AffCreateHandle */ -int AffInitHandle(void **pp_handle) { +static int AffCreateHandle(void **pp_handle) { *pp_handle=NULL; - return 0; + return AFF_OK; +} + +/* + * AffDestroyHandle + */ +static int AffDestroyHandle(void **pp_handle) { + *pp_handle=NULL; + return AFF_OK; } /* * AffOpen */ -int AffOpen(void **pp_handle, - const char **pp_filename_arr, - uint64_t filename_arr_len) +static int AffOpen(void **pp_handle, + const char **pp_filename_arr, + uint64_t filename_arr_len) { - // We need at least one file - if(filename_arr_len==0) return 1; + // We need exactly one file + if(filename_arr_len==0) return AFF_NO_INPUT_FILES; + if(filename_arr_len>1) return AFF_TOO_MANY_INPUT_FILES; // Open AFF file *pp_handle=(void*)af_open(pp_filename_arr[0],O_RDONLY,0); - if(!*pp_handle) { + if(*pp_handle==NULL) { // LOG_ERROR("Couldn't open AFF file!\n") - return 1; + return AFF_OPEN_FAILED; } // Encrypted images aren't supported for now - if(af_cannot_decrypt((AFFILE*)*p_handle)) { - // LOG_ERROR("Encrypted AFF input images aren't supported yet!\n") - return 1; + if(af_cannot_decrypt((AFFILE*)*pp_handle)) { + AffClose(pp_handle); + return AFF_ENCRYPTION_UNSUPPORTED; } - return 0; + return AFF_OK; +} + +/* + * AffClose + */ +static int AffClose(void **pp_handle) { + if(af_close((AFFILE*)*pp_handle)!=0) return AFF_CLOSE_FAILED; + return AFF_OK; } /* * AffSize */ -int AffSize(void *p_handle, uint64_t *p_size) { +static int AffSize(void *p_handle, uint64_t *p_size) { *p_size=af_seek((AFFILE*)p_handle,0,SEEK_END); - // TODO: Check for error - return 0; + // TODO: Check for error. Unfortunately, I don't know how :(. + return AFF_OK; } /* * AffRead */ -int AffRead(void *p_handle, - uint64_t offset, - unsigned char *p_buf, - uint32_t count) +static int AffRead(void *p_handle, + uint64_t offset, + char *p_buf, + uint32_t count) { - af_seek((AFFILE*)p_handle,offset,SEEK_SET); - // TODO: Check for error - if(af_read((AFFILE*)p_handle,p_buf,count)!=count) { - // LOG_ERROR("Couldn't read %zd bytes from offset %" PRIu64 - // "!\n",ToRead,offset); - return 1; + if(af_seek((AFFILE*)p_handle,offset,SEEK_SET)!=offset) { + return AFF_SEEK_FAILED; } - return 0; -} - -/* - * AffClose - */ -int AffClose(void **pp_handle) { - af_close((AFFILE*)*p_handle); - // TODO: Check for error - return 0; + if(af_read((AFFILE*)p_handle,(unsigned char*)p_buf,count)!=count) { + return AFF_READ_FAILED; + } + return AFF_OK; } /* * AffOptionsHelp */ -const char* AffOptionsHelp() { +static const char* AffOptionsHelp() { return NULL; } /* * AffOptionsParse */ -int AffOptionsParse(void *p_handle, char *p_options, char **pp_error) { - return 0; +static int AffOptionsParse(void *p_handle, char *p_options, char **pp_error) { + return AFF_OK; } /* * AffGetInfofileContent */ -int AffGetInfofileContent(void *p_handle, const char **pp_info_buf) { +static int AffGetInfofileContent(void *p_handle, char **pp_info_buf) { // TODO *pp_info_buf=NULL; - return 0; + return AFF_OK; +} + +/* + * AffGetErrorMessage + */ +static const char* AffGetErrorMessage(int err_num) { + switch(err_num) { + case AFF_MEMALLOC_FAILED: + return "Unable to allocate memory"; + break; + case AFF_NO_INPUT_FILES: + return "No input file(s) specified"; + break; + case AFF_TOO_MANY_INPUT_FILES: + return "Too many input files specified"; + break; + case AFF_OPEN_FAILED: + return "Unable to open EWF file(s)"; + break; + case AFF_CLOSE_FAILED: + return "Unable to close EWF file(s)"; + break; + case AFF_ENCRYPTION_UNSUPPORTED: + return "Encrypted AFF files are currently not supported"; + break; + case AFF_SEEK_FAILED: + return "Unable to seek into EWF data"; + break; + case AFF_READ_FAILED: + return "Unable to read EWF data"; + break; + default: + return "Unknown error"; + } } /* * AffFreeBuffer */ -void AffFreeBuffer(void *p_buf) { +static void AffFreeBuffer(void *p_buf) { free(p_buf); } /* - ----- Change history ----- + ----- Change log ----- 20140724: * Initial version implementing AffOpen, AffSize, AffRead, AffClose, AffOptionsHelp, AffOptionsParse and AffFreeBuffer + 20140804: * Added error handling and AffGetErrorMessage */ diff --git a/trunk/libxmount_input/libxmount_input_aff/libxmount_input_aff.h b/trunk/libxmount_input/libxmount_input_aff/libxmount_input_aff.h new file mode 100644 index 0000000..df6e6a6 --- /dev/null +++ b/trunk/libxmount_input/libxmount_input_aff/libxmount_input_aff.h @@ -0,0 +1,61 @@ +/******************************************************************************* +* xmount Copyright (c) 2008-2014 by Gillen Daniel * +* * +* 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 3 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, see . * +*******************************************************************************/ + +#ifndef LIBXMOUNT_INPUT_AFF_H +#define LIBXMOUNT_INPUT_AFF_H + +/******************************************************************************* + * Error codes + ******************************************************************************/ +enum { + AFF_OK=0, + AFF_MEMALLOC_FAILED, + AFF_NO_INPUT_FILES, + AFF_TOO_MANY_INPUT_FILES, + AFF_OPEN_FAILED, + AFF_CLOSE_FAILED, + AFF_ENCRYPTION_UNSUPPORTED, + AFF_SEEK_FAILED, + AFF_READ_FAILED +}; + +/******************************************************************************* + * Forward declarations + ******************************************************************************/ +static int AffCreateHandle(void **pp_handle); +static int AffDestroyHandle(void **pp_handle); +static int AffOpen(void **pp_handle, + const char **pp_filename_arr, + uint64_t filename_arr_len); +static int AffClose(void **pp_handle); +static int AffSize(void *p_handle, + uint64_t *p_size); +static int AffRead(void *p_handle, + uint64_t seek, + char *p_buf, + uint32_t count); +static const char* AffOptionsHelp(); +static int AffOptionsParse(void *p_handle, + char *p_options, + char **pp_error); +static int AffGetInfofileContent(void *p_handle, + char **pp_info_buf); +static const char* AffGetErrorMessage(int err_num); +static void AffFreeBuffer(void *p_buf); + +#endif // LIBXMOUNT_INPUT_AFF_H + diff --git a/trunk/libxmount_input/libxmount_input_dd/CMakeLists.txt b/trunk/libxmount_input/libxmount_input_dd/CMakeLists.txt index 5b8dc1f..cd8d34c 100644 --- a/trunk/libxmount_input/libxmount_input_dd/CMakeLists.txt +++ b/trunk/libxmount_input/libxmount_input_dd/CMakeLists.txt @@ -1,6 +1,10 @@ -project(libxmount_input_dd) +if(POLICY CMP0042) + cmake_policy(SET CMP0042 NEW) # CMake 3.0 +endif(POLICY CMP0042) + +project(libxmount_input_dd C) add_library(xmount_input_dd SHARED libxmount_input_dd.c) install(TARGETS xmount_input_dd DESTINATION lib/xmount) diff --git a/trunk/libxmount_input/libxmount_input_dd/libxmount_input_dd.c b/trunk/libxmount_input/libxmount_input_dd/libxmount_input_dd.c index 0ac0ae6..130bfd8 100644 --- a/trunk/libxmount_input/libxmount_input_dd/libxmount_input_dd.c +++ b/trunk/libxmount_input/libxmount_input_dd/libxmount_input_dd.c @@ -1,409 +1,391 @@ /******************************************************************************* * xmount Copyright (c) 2008-2013 by Gillen Daniel * * * * This module has been written by Guy Voncken. It contains the functions for * * accessing dd images. Split dd is supported as well. * * * -* xmount is a small tool to "fuse mount" various harddisk image formats as dd, * -* vdi, vhd or vmdk files and enable virtual write access to them. * -* * * 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 3 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, see . * *******************************************************************************/ #include #include #include #include #include #include #include "../libxmount_input.h" - #include "libxmount_input_dd.h" -/******************************************************************************* - * Forward declarations - ******************************************************************************/ -int DdCreateHandle(void **pp_handle); -int DdDestroyHandle(void **pp_handle); -int DdOpen(void **pp_handle, - const char **pp_filename_arr, - uint64_t filename_arr_len); -int DdClose(void **pp_handle); -int DdSize(void *p_handle, - uint64_t *p_size); -int DdRead(void *p_handle, - uint64_t seek, - char *p_buf, - uint32_t count); -const char* DdOptionsHelp(); -int DdOptionsParse(void *p_handle, - char *p_options, - char **pp_error); -int DdGetInfofileContent(void *p_handle, - char **pp_info_buf); -void DdFreeBuffer(void *p_buf); - /******************************************************************************* * LibXmount_Input API implementation ******************************************************************************/ /* * LibXmount_Input_GetApiVersion */ uint8_t LibXmount_Input_GetApiVersion() { return LIBXMOUNT_INPUT_API_VERSION; } /* * LibXmount_Input_GetSupportedFormats */ const char* LibXmount_Input_GetSupportedFormats() { return "dd\0\0"; } /* * LibXmount_Input_GetFunctions */ void LibXmount_Input_GetFunctions(ts_LibXmountInputFunctions *p_functions) { p_functions->CreateHandle=&DdCreateHandle; p_functions->DestroyHandle=&DdDestroyHandle; p_functions->Open=&DdOpen; p_functions->Close=&DdClose; p_functions->Size=&DdSize; p_functions->Read=&DdRead; p_functions->OptionsHelp=&DdOptionsHelp; p_functions->OptionsParse=&DdOptionsParse; p_functions->GetInfofileContent=&DdGetInfofileContent; + p_functions->GetErrorMessage=&DdGetErrorMessage; p_functions->FreeBuffer=&DdFreeBuffer; } /******************************************************************************* * Private ******************************************************************************/ // --------------------------- // Internal static functions // --------------------------- -static inline unsigned long long DdGetCurrentSeekPos (t_pPiece pPiece) +static inline uint64_t DdGetCurrentSeekPos (t_pPiece pPiece) { return ftello (pPiece->pFile); } static inline int DdSetCurrentSeekPos (t_pPiece pPiece, uint64_t Val, int Whence) { if (fseeko (pPiece->pFile, Val, Whence) != 0) return DD_CANNOT_SEEK; return DD_OK; } -int DdDestroyHandle0 (t_pdd *ppdd) +static int DdDestroyHandle0 (t_pdd *ppdd) { t_pdd pdd = *ppdd; t_pPiece pPiece; int CloseErrors = 0; if (pdd->pPieceArr) { for (int i=0; i < pdd->Pieces; i++) { pPiece = &pdd->pPieceArr[i]; if (pPiece->pFile) if (fclose (pPiece->pFile)) CloseErrors++; if (pPiece->pFilename) free (pPiece->pFilename); } free (pdd->pPieceArr); } if (pdd->pInfo) free (pdd->pInfo); free (pdd); *ppdd = NULL; if (CloseErrors) return DD_CANNOT_CLOSE_FILE; return DD_OK; } static int DdCreateHandle0 (t_pdd pdd, unsigned FilenameArrLen, const char **ppFilenameArr) { t_pPiece pPiece; pdd->Pieces = FilenameArrLen; pdd->pPieceArr = (t_pPiece) malloc (pdd->Pieces * sizeof(t_Piece)); if (pdd->pPieceArr == NULL) { (void) DdDestroyHandle0 (&pdd); return DD_MEMALLOC_FAILED; } pdd->TotalSize = 0; for (int i=0; i < pdd->Pieces; i++) { pPiece = &pdd->pPieceArr[i]; pPiece->pFilename = strdup (ppFilenameArr[i]); if (pPiece->pFilename == NULL) { (void) DdDestroyHandle0 (&pdd); return DD_MEMALLOC_FAILED; } pPiece->pFile = fopen (pPiece->pFilename, "r"); if (pPiece->pFile == NULL) { (void) DdDestroyHandle0 (&pdd); return DD_FILE_OPEN_FAILED; } CHK(DdSetCurrentSeekPos(pPiece, 0, SEEK_END)) pPiece->FileSize = DdGetCurrentSeekPos (pPiece); pdd->TotalSize += pPiece->FileSize; } asprintf (&pdd->pInfo, "dd image made of %u pieces, %llu bytes in total (%0.3f GiB)", pdd->Pieces, pdd->TotalSize, pdd->TotalSize / (1024.0*1024.0*1024.0)); return DD_OK; } -int DdRead0 (t_pdd pdd, uint64_t Seek, char *pBuffer, uint32_t *pCount) +static int DdRead0 (t_pdd pdd, uint64_t Seek, char *pBuffer, uint32_t *pCount) { t_pPiece pPiece; int i; // Find correct piece to read from // ------------------------------- for (i=0; iPieces; i++) { pPiece = &pdd->pPieceArr[i]; if (Seek < pPiece->FileSize) break; Seek -= pPiece->FileSize; } if (i >= pdd->Pieces) return DD_READ_BEYOND_END_OF_IMAGE; // Read from this piece // -------------------- CHK (DdSetCurrentSeekPos (pPiece, Seek, SEEK_SET)) *pCount = GETMIN (*pCount, pPiece->FileSize - Seek); if (fread (pBuffer, *pCount, 1, pPiece->pFile) != 1) return DD_CANNOT_READ_DATA; return DD_OK; } // --------------- // API functions // --------------- /* * DdCreateHandle */ -int DdCreateHandle(void **pp_handle) { +static int DdCreateHandle(void **pp_handle) { t_pdd p_dd=(t_pdd)*pp_handle; p_dd=(t_pdd)malloc(sizeof(t_dd)); if(p_dd==NULL) return DD_MEMALLOC_FAILED; memset(p_dd,0,sizeof(t_dd)); return DD_OK; } /* * DdDestroyHandle */ -int DdDestroyHandle(void **pp_handle) { +static int DdDestroyHandle(void **pp_handle) { // TODO: Implement return DD_OK; } /* * DdOpen */ -int DdOpen(void **pp_handle, - const char **pp_filename_arr, - uint64_t filename_arr_len) +static int DdOpen(void **pp_handle, + const char **pp_filename_arr, + uint64_t filename_arr_len) { CHK(DdCreateHandle0((t_pdd)*pp_handle,filename_arr_len,pp_filename_arr)) return DD_OK; } /* * DdClose */ -int DdClose(void **pp_handle) { +static int DdClose(void **pp_handle) { CHK (DdDestroyHandle0((t_pdd*)pp_handle)) return DD_OK; } /* * DdSize */ -int DdSize(void *p_handle, uint64_t *p_size) { +static int DdSize(void *p_handle, uint64_t *p_size) { *p_size=((t_pdd)p_handle)->TotalSize; return DD_OK; } /* * DdRead */ -int DdRead(void *p_handle, - uint64_t seek, - char *p_buf, - uint32_t count) +static int DdRead(void *p_handle, + uint64_t seek, + char *p_buf, + uint32_t count) { uint32_t remaining=count; uint32_t read; if((seek+count)>((t_pdd)p_handle)->TotalSize) { return DD_READ_BEYOND_END_OF_IMAGE; } do { read=remaining; CHK(DdRead0((t_pdd)p_handle,seek,p_buf,&read)) remaining-=read; p_buf+=read; seek+=read; } while(remaining); return DD_OK; } /* * DdOptionsHelp */ -const char* DdOptionsHelp() { +static const char* DdOptionsHelp() { return NULL; } /* * DdOptionsParse */ -int DdOptionsParse(void *p_handle, char *p_options, char **pp_error) { +static int DdOptionsParse(void *p_handle, char *p_options, char **pp_error) { return DD_OK; } /* * DdGetInfofileContent */ -int DdGetInfofileContent(void *p_handle, char **pp_info_buf) { +static int DdGetInfofileContent(void *p_handle, char **pp_info_buf) { // TODO: Rather then copying, generate info text once here. It won't be used // after this anymore. *pp_info_buf=(char*)malloc(strlen(((t_pdd)p_handle)->pInfo)+1); if(*pp_info_buf==NULL) { return DD_MEMALLOC_FAILED; } strcpy(*pp_info_buf,((t_pdd)p_handle)->pInfo); return DD_OK; } +/* + * DdGetErrorMessage + */ +static const char* DdGetErrorMessage(int err_num) { + // TODO + return ""; +} + /* * DdFreeBuffer */ -void DdFreeBuffer(void *p_buf) { +static void DdFreeBuffer(void *p_buf) { free(p_buf); } // ----------------------------------------------------- // Small main routine for testing // It a split dd file to non-split dd // ----------------------------------------------------- #ifdef DD_MAIN_FOR_TESTING int main(int argc, const char *argv[]) { t_pdd pdd; uint64_t TotalSize; uint64_t Remaining; uint64_t Read; uint64_t Pos; uint32_t BuffSize = 1024; char Buff[BuffSize]; FILE *pFile; int Percent; int PercentOld; int rc; printf ("Split DD to DD converter\n"); if (argc < 3) { printf ("Usage: %s
<...>
\n", argv[0]); exit (1); } if (DdOpen ((void**)&pdd, argc-2, &argv[1]) != DD_OK) { printf ("Cannot open split dd file\n"); exit (1); } CHK (DdSize ((void*)pdd, &TotalSize)) printf ("Total size: %llu bytes\n", TotalSize); Remaining = TotalSize; pFile = fopen (argv[argc-1], "w"); if (pFile == NULL) { printf ("Cannot open destination file\n"); exit (1); } Remaining = TotalSize; Pos = 0; PercentOld = -1; while (Remaining) { Read = GETMIN (Remaining, BuffSize); rc = DdRead ((void*)pdd, Pos, &Buff[0], Read); if (rc != DD_OK) { printf ("Error %d while calling DdRead\n", rc); exit (1); } if (fwrite (Buff, Read, 1, pFile) != 1) { printf ("Could not write to destinationfile\n"); exit (2); } Remaining -= Read; Pos += Read; Percent = (100*Pos) / TotalSize; if (Percent != PercentOld) { printf ("\r%d%% done...", Percent); PercentOld = Percent; } } if (fclose (pFile)) { printf ("Error while closing destinationfile\n"); exit (3); } printf ("\n"); return 0; } -#endif +#endif // DD_MAIN_FOR_TESTING diff --git a/trunk/libxmount_input/libxmount_input_dd/libxmount_input_dd.h b/trunk/libxmount_input/libxmount_input_dd/libxmount_input_dd.h index 7a37b86..ed45c6b 100644 --- a/trunk/libxmount_input/libxmount_input_dd/libxmount_input_dd.h +++ b/trunk/libxmount_input/libxmount_input_dd/libxmount_input_dd.h @@ -1,98 +1,120 @@ /******************************************************************************* * xmount Copyright (c) 2008-2013 by Gillen Daniel * * * * This module has been written by Guy Voncken. It contains the functions for * * accessing dd images. Split dd is supported as well. * * * * xmount is a small tool to "fuse mount" various harddisk image formats as dd, * * vdi, vhd or vmdk files and enable virtual write access to them. * * * * 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 3 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, see . * *******************************************************************************/ -#ifndef DD_H -#define DD_H +#ifndef LIBXMOUNT_INPUT_DD_H +#define LIBXMOUNT_INPUT_DD_H -typedef struct _t_dd *t_pdd; - -// Possible error codes +/******************************************************************************* + * Error codes + ******************************************************************************/ enum { DD_OK = 0, DD_FOUND, DD_MEMALLOC_FAILED=100, DD_FILE_OPEN_FAILED, DD_CANNOT_READ_DATA, DD_CANNOT_CLOSE_FILE, DD_CANNOT_SEEK, DD_READ_BEYOND_END_OF_IMAGE }; // ---------------------- // Constant definitions // ---------------------- #define GETMAX(a,b) ((a)>(b)?(a):(b)) #define GETMIN(a,b) ((a)<(b)?(a):(b)) // --------------------- // Types and strutures // --------------------- -typedef struct -{ +typedef struct { char *pFilename; unsigned long long FileSize; FILE *pFile; } t_Piece, *t_pPiece; -typedef struct _t_dd -{ +typedef struct _t_dd { t_pPiece pPieceArr; unsigned int Pieces; unsigned long long TotalSize; char *pInfo; -} t_dd; +} t_dd, *t_pdd; // ---------------- // Error handling // ---------------- #ifdef DD_DEBUG #define CHK(ChkVal) \ { \ int ChkValRc; \ if ((ChkValRc=(ChkVal)) != DD_OK) \ { \ printf ("Err %d in %s, %d\n", ChkValRc, __FILE__, __LINE__); \ return ChkValRc; \ } \ } #define DEBUG_PRINTF(pFormat, ...) \ printf (pFormat, ##__VA_ARGS__); #else #define CHK(ChkVal) \ { \ int ChkValRc; \ if ((ChkValRc=(ChkVal)) != DD_OK) \ return ChkValRc; \ } #define DEBUG_PRINTF(...) #endif -#endif +/******************************************************************************* + * Forward declarations + ******************************************************************************/ +static int DdCreateHandle(void **pp_handle); +static int DdDestroyHandle(void **pp_handle); +static int DdOpen(void **pp_handle, + const char **pp_filename_arr, + uint64_t filename_arr_len); +static int DdClose(void **pp_handle); +static int DdSize(void *p_handle, + uint64_t *p_size); +static int DdRead(void *p_handle, + uint64_t seek, + char *p_buf, + uint32_t count); +static const char* DdOptionsHelp(); +static int DdOptionsParse(void *p_handle, + char *p_options, + char **pp_error); +static int DdGetInfofileContent(void *p_handle, + char **pp_info_buf); +static const char* DdGetErrorMessage(int err_num); +static void DdFreeBuffer(void *p_buf); + +#endif // LIBXMOUNT_INPUT_DD_H diff --git a/trunk/libxmount_input/libxmount_input_ewf/CMakeLists.txt b/trunk/libxmount_input/libxmount_input_ewf/CMakeLists.txt index e22c5dc..15afa7c 100644 --- a/trunk/libxmount_input/libxmount_input_ewf/CMakeLists.txt +++ b/trunk/libxmount_input/libxmount_input_ewf/CMakeLists.txt @@ -1,13 +1,13 @@ if(POLICY CMP0042) cmake_policy(SET CMP0042 NEW) # CMake 3.0 endif(POLICY CMP0042) -project(libxmount_input_ewf) +project(libxmount_input_ewf C) add_library(xmount_input_ewf SHARED libxmount_input_ewf.c) include_directories(${LIBEWF_INCLUDE_DIRS}) set(LIBS ${LIBS} ${LIBEWF_LIBRARIES}) target_link_libraries(xmount_input_ewf ${LIBS}) install(TARGETS xmount_input_ewf DESTINATION lib/xmount) diff --git a/trunk/src/CMakeLists.txt b/trunk/src/CMakeLists.txt index 950eef4..7cffe2c 100644 --- a/trunk/src/CMakeLists.txt +++ b/trunk/src/CMakeLists.txt @@ -1,24 +1,20 @@ -project(xmount) - add_definitions(-DXMOUNT_VERSION="0.7.0") if(NOT APPLE) include_directories(${LIBFUSE_INCLUDE_DIRS}) set(LIBS ${LIBS} ${LIBFUSE_LIBRARIES}) else(NOT APPLE) include_directories(${LIBOSXFUSE_INCLUDE_DIRS}) set(LIBS ${LIBS} ${LIBOSXFUSE_LIBRARIES}) endif(NOT APPLE) set(LIBS ${LIBS} "dl") -#set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} "-fno-strict-aliasing") - add_definitions(-DXMOUNT_LIBRARY_PATH="${CMAKE_INSTALL_PREFIX}/lib/xmount") add_executable(xmount xmount.c md5.c) target_link_libraries(xmount ${LIBS}) install(TARGETS xmount DESTINATION bin)