📄 vnode_ewf.cpp
字号:
/** ** AFF/libewf glue ** ** (C) 2006 by Simson L. Garfinkel ** ** **/#include "config.h"#include "afflib.h"#include "afflib_i.h"#ifdef USE_LIBEWF#include <ctype.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include "vnode_ewf.h"/* We're gonna include libewf.h now, which causes problems, because libewf.h currently * includes an autoconf-generated config.h file */#undef PACKAGE#undef PACKAGE_BUGREPORT#undef PACKAGE_NAME#undef PACKAGE_STRING#undef PACKAGE_TARNAME#undef PACKAGE_VERSION#undef VERSION#ifdef HAVE_LIBEWF_H#include "libewf.h"#else#error EWF support requires libewf, but HAVE_LIBEWF_H is not defined#endif/**************************************************************** *** Service routines ****************************************************************/#define EWF_HANDLE(af) ((libewf_handle_t *)af->vnodeprivate)/**************************************************************** *** AFFLIB Glue Follows ****************************************************************//* Return 1 if a file is a ewf file... */static int ewf_identify_file(const char *filename,int exists){ return libewf_check_file_signature(filename)==1 ? 1 : 0;}static int ewf_open(AFFILE *af){ if(strchr(af->fname,'.')==0) return -1; // need a '.' in the filename /* See how many files there are to open */ char **files = (char **)malloc(sizeof(char *)); int nfiles = 1; files[0] = strdup(af->fname); char fname[MAXPATHLEN+1]; strlcpy(fname,af->fname,sizeof(fname)); char *ext = strrchr(fname,'.')+1; if(ext-fname > MAXPATHLEN-4){ warn("ewf_open: %s: filename too long",af->fname); return -1; } /* Now open .E02 through .E99 and then .AAA through .ZZZ if they exist... */ for(int i=2;i<=99;i++){ sprintf(ext+1,"%02d",i); if(access(fname,R_OK)!=0) break; files = (char **)realloc(files,(nfiles+1) * sizeof(char *)); files[nfiles] = strdup(fname); nfiles++; } for(int i=4*26*26;i<=26*26*26;i++){ sprintf(ext, "%c%c%c", i/26/26%26+'A', i/26%26+'A', i%26+'A'); if(access(fname,R_OK)!=0) break; // file can't be read files = (char **)realloc(files,(nfiles+1) * sizeof(char *)); files[nfiles] = strdup(fname); nfiles++; } LIBEWF_HANDLE *handle = libewf_open( files, nfiles, LIBEWF_OPEN_READ ); if(!handle){ warn("Unable to open EWF image file"); for(int i=0;i<nfiles;i++) free(files[i]); free(files); return -1; } af->image_size = libewf_get_media_size(handle); if(af->image_size == 0){ warn("EFW error: image size==0?"); for(int i=0;i<nfiles;i++) free(files[i]); free(files); return -1; } af->vnodeprivate = (void *)handle; af->image_pagesize = libewf_get_chunk_size(handle); for(int i=0;i<nfiles;i++) free(files[i]); free(files); return 0;}static int ewf_vstat(AFFILE *af,struct af_vnode_info *vni){ LIBEWF_HANDLE *handle = EWF_HANDLE(af); vni->imagesize = libewf_get_media_size(handle); vni->pagesize = libewf_get_chunk_size(handle); vni->supports_metadata = 1; vni->changable_pagesize = 0; vni->changable_sectorsize = 0; vni->supports_compression = 1; vni->has_pages = 1; // debatable return 0;}static int ewf_read(AFFILE *af, unsigned char *buf, uint64 pos,size_t count){ LIBEWF_HANDLE *handle = EWF_HANDLE(af); return libewf_read_random(handle,buf,(uint64_t)count,pos);}static int ewf_write(AFFILE *af, unsigned char *buf, uint64 pos,size_t count){ LIBEWF_HANDLE *handle = EWF_HANDLE(af); return libewf_write_random(handle,buf,(uint64_t)count,pos);}static int ewf_close(AFFILE *af){ LIBEWF_HANDLE *handle = EWF_HANDLE(af); if(libewf_close(handle)!=1) return -1; return 0;}static int ewf_rewind_seg(AFFILE *af){ af->cur_page = -1; // starts at the metadata return 0;}/* return the length of a string up to a max */static int strlenp(const unsigned char *data,int max){ for(int i=0;i<max;i++){ if(data[i]==0) return i; } return max;}static int ewf_get_seg(AFFILE *af,const char *name, unsigned long *arg,unsigned char *data,size_t *datalen){ LIBEWF_HANDLE *handle = EWF_HANDLE(af); int64 segnum = af_segname_page_number(name); if(segnum<0){ /* See if it is a page name we understand */ if(strcmp(name,AF_PAGESIZE)==0){ if(arg) *arg = libewf_get_chunk_size(handle); if(datalen) *datalen = 0; return 0; } if(strcmp(name,AF_IMAGESIZE)==0){ if(arg) *arg = 0; if(datalen==0 || *datalen==0) return 0; if(*datalen<8) return -2; uint64 quad = libewf_get_media_size(handle); struct aff_quad q; q.low = htonl((unsigned long)(quad & 0xffffffff)); q.high = htonl((unsigned long)(quad >> 32)); memcpy(data,&q,8); return 0; } if(strcmp(name,AF_SECTORSIZE)==0){ if(arg) *arg = libewf_get_bytes_per_sector(handle); if(datalen) *datalen = 0; return 0; } if(strcmp(name,AF_DEVICE_SECTORS)==0){ /* Is this in flag or a quad word? */ if(arg) *arg = libewf_get_media_size(handle) / libewf_get_bytes_per_sector(handle); if(datalen) *datalen = 0; return 0; } if(strcmp(name,AF_CASE_NUM)==0){ if(data && datalen){ libewf_get_header_value_case_number(handle,(libewf_char_t *)data,*datalen); *datalen = strlenp(data,*datalen); if(arg) *arg = 0; } return 0; } if(strcmp(name,AF_IMAGE_GID)==0){ if(data && datalen){ libewf_get_guid(handle,data,*datalen); if(arg) *arg = 0; } return 0; } if(strcmp(name,AF_ACQUISITION_NOTES)==0){ if(data && datalen){ libewf_get_header_value_notes(handle,(libewf_char_t *)data,*datalen); *datalen = strlenp(data,*datalen); } if(data==0 && datalen){ /* Caller wants to learn size of the notes */ unsigned char tmp[128]; memset(tmp,0,sizeof(tmp)); *datalen = sizeof(tmp); libewf_get_header_value_notes(handle,(libewf_char_t *)tmp,*datalen); *datalen = strlenp(tmp,*datalen); } if(arg) *arg = 0; return 0; } return -1; // don't know this header } /* Get the segment number */ if(data==0 && datalen){ *datalen = libewf_get_chunk_size(handle); return 0; } size_t r = libewf_read_random(handle,data,*datalen,segnum * libewf_get_chunk_size(handle)); return 0; // should probably put in some error checking}const char *emap[] = { AF_PAGESIZE, AF_IMAGESIZE, AF_SECTORSIZE, AF_DEVICE_SECTORS, AF_CASE_NUM, AF_IMAGE_GID, AF_ACQUISITION_NOTES, 0};static int ewf_get_next_seg(AFFILE *af,char *segname,size_t segname_len,unsigned long *arg, unsigned char *data,size_t *datalen){ /* Figure out what the next segment would be, then get it */ /* Metadata first */ if(af->cur_page<0){ /* Find out how many mapped segments there are */ int mapped=0; for(mapped=0;emap[mapped];mapped++){ } if(-af->cur_page >= mapped ){ af->cur_page = 0; goto get_next_data_seg; } int which = 0 - af->cur_page; // which one to get af->cur_page--; // go to the next one if(segname_len < strlen(emap[which])) return -2; // not enough room for segname strlcpy(segname,emap[which],segname_len); // give caller the name of the mapped segment. return ewf_get_seg(af,segname,arg,data,datalen); } get_next_data_seg: if(af->cur_page * af->image_pagesize >= af->image_size) return -1; // end of list /* Make the segment name */ char pagename[AF_MAX_NAME_LEN]; // memset(pagename,0,sizeof(pagename)); snprintf(pagename,sizeof(pagename),AF_PAGE,af->cur_page++); int r = 0; /* Get the segment, if it is wanted */ if(data) r = ewf_get_seg(af,pagename,arg,data,datalen); /* If r==0 and there is room for copying in the segment name, return it */ if(r==0){ if(strlen(pagename)+1 < segname_len){ strlcpy(segname,pagename,segname_len); return 0; } /* segname wasn't big enough */ return -2; } return r; // some other error}struct af_vnode vnode_ewf = { AF_IDENTIFY_EWF, AF_VNODE_TYPE_PRIMITIVE, "LIBEWF", ewf_identify_file, ewf_open, ewf_close, ewf_vstat, ewf_get_seg, // get seg ewf_get_next_seg, // get_next_seg ewf_rewind_seg, // rewind_seg 0, // update_seg 0, // del_seg ewf_read, // read ewf_write // write};#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -