int reverse_test() { char wbuf[1024]; char rbuf[1024]; printf("Reverse write test...\n"); for(int pass=1;pass<=2;pass++){ AFFILE *af = open_testfile("test_reverse",pass==1); for(int i=MAX_FMTS-1;i>=0;i--){ sprintf(wbuf,fmt,i); af_seek(af,strlen(wbuf)*i,SEEK_SET); if(pass==1){ if(af_write(af,(unsigned char *)wbuf,strlen(wbuf))!=(int)strlen(wbuf)){ err(1,"Attempt to write buffer %d failed\n",i); } } if(pass==2){ memset(rbuf,0,sizeof(rbuf)); if(af_read(af,(unsigned char *)rbuf,strlen(wbuf))!=(int)strlen(wbuf)){ err(1,"Attempt to read buffer %d failed\n",i); } if(strcmp(rbuf,wbuf)!=0){ errx(1,"Data doesn't verify.\nWrote: '%s'\nRead: '%s'\n",wbuf,rbuf); } } } af_close(af); } printf("\nReverse test passes.\n"); printf("======================\n\n"); return 0; }
int aff::vread(int fd, void *buff, unsigned int size) { int result; fdinfo* fi; AffNode* affNode = NULL; try { fi = this->__fdm->get(fd); affNode = dynamic_cast<AffNode* >(fi->node); } catch (...) { return (-1); } mutex_lock(&io_mutex); af_seek(affNode->affile, (int64_t)fi->offset, SEEK_SET); result = af_read(affNode->affile, (unsigned char*)buff, size); if (result > 0) fi->offset += result; mutex_unlock(&io_mutex); return (result); }
/* Note: The routine -assumes- we are under a lock on &(img_info->cache_lock)) */ static ssize_t aff_read(TSK_IMG_INFO * img_info, TSK_OFF_T offset, char *buf, size_t len) { ssize_t cnt; IMG_AFF_INFO *aff_info = (IMG_AFF_INFO *) img_info; if (tsk_verbose) tsk_fprintf(stderr, "aff_read: byte offset: %" PRIuOFF " len: %" PRIuOFF "\n", offset, len); if (offset > img_info->size) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_IMG_READ_OFF); tsk_error_set_errstr("aff_read - %" PRIuOFF, offset); return -1; } if (aff_info->seek_pos != offset) { if (af_seek(aff_info->af_file, offset, SEEK_SET) != offset) { tsk_error_reset(); // @@@ ADD more specific error messages tsk_error_set_errno(TSK_ERR_IMG_SEEK); tsk_error_set_errstr("aff_read - %" PRIuOFF " - %s", offset, strerror(errno)); return -1; } aff_info->seek_pos = offset; } cnt = af_read(aff_info->af_file, (unsigned char *) buf, len); if (cnt < 0) { // @@@ Add more specific error message tsk_error_reset(); tsk_error_set_errno(TSK_ERR_IMG_READ); tsk_error_set_errstr("aff_read - offset: %" PRIuOFF " - len: %" PRIuSIZE " - %s", offset, len, strerror(errno)); return -1; } /* AFF will return 0 if the page does not exist -- fill the * buffer with zeros in this case */ if (cnt == 0) { // @@@ We could improve this if there is an AFF call // to see if the data exists or not if ((af_eof(aff_info->af_file) == 0) && (offset + len < img_info->size)) { memset(buf, 0, len); cnt = len; } } aff_info->seek_pos += cnt; return cnt; }
static PyObject * affile_seek(affile *self, PyObject *args, PyObject *kwds) { int64_t offset=0; int whence=0; static char *kwlist[] = {"offset", "whence", NULL}; if(!PyArg_ParseTupleAndKeywords(args, kwds, "L|i", kwlist, &offset, &whence)) return NULL; if(af_seek(self->af, offset, whence) < 0) return PyErr_Format(PyExc_IOError, "libaff_seek_offset failed"); Py_RETURN_NONE; }
void large_file_test() { int pagesize = 1024*1024; // megabyte sized segments int64_t num_segments = 5000; int64_t i; char fn[1024]; printf("Large file test... Creating a %"I64d"MB file...\n",pagesize*num_segments/(1024*1024)); filename(fn,sizeof(fn),"large_file"); AFFILE *af = af_open(fn,O_CREAT|O_RDWR|O_TRUNC,0666); unsigned char *buf = (unsigned char *)malloc(pagesize); memset(buf,'E', pagesize); af_enable_compression(af,opt_compression_type,opt_compression_level); af_set_pagesize(af,pagesize); af_set_maxsize(af,(int64_t)pagesize * 600); for(i=0;i<num_segments;i++){ sprintf((char *)buf,"%"I64d" page is put here",i); if(i%25==0) printf("\rWriting page %"I64d"\r",i); if(af_write(af,buf,pagesize)!=pagesize){ err(1,"Can't write page %"I64d,i); } } printf("\n\n"); /* Now let's just read some test locations */ for(i=0;i<num_segments;i+=num_segments/25){ // check a few places int r; af_seek(af,pagesize*i,SEEK_SET); r = af_read(af,buf,1024); // just read a bit if(r!=1024){ err(1,"Tried to read 1024 bytes; got %d\n",r); } if(atoi((char *)buf)!=i){ err(1,"at page %"I64d", expected %"I64d", got %s\n",i,i,buf); } printf("Page %"I64d" validates\n",i); } af_close(af); if(unlink("large_file.aff")){ err(1,"Can't delete large_file.aff"); } printf("Large file test passes\n"); }
static SSIZE_T aff_read_random(IMG_INFO * img_info, SSIZE_T vol_offset, char *buf, OFF_T len, OFF_T offset) { SSIZE_T cnt; IMG_AFF_INFO *aff_info = (IMG_AFF_INFO *) img_info; off_t tot_offset = offset + vol_offset; if (verbose) fprintf(stderr, "aff_read_random: byte offset: %" PRIuOFF " len: %" PRIuOFF "\n", offset, len); if (aff_info->seek_pos != tot_offset) { if ((off_t) af_seek(aff_info->af_file, tot_offset, SEEK_SET) != tot_offset) { // @@@ ADD more specific error messages tsk_errno = TSK_ERR_IMG_SEEK; snprintf(tsk_errstr, TSK_ERRSTR_L, "aff_read_random - %" PRIuOFF " - %s", tot_offset, strerror(errno)); tsk_errstr2[0] = '\0'; return -1; } aff_info->seek_pos = tot_offset; } cnt = af_read(aff_info->af_file, (unsigned char *) buf, len); if (cnt == -1) { // @@@ Add more specific error message tsk_errno = TSK_ERR_IMG_READ; snprintf(tsk_errstr, TSK_ERRSTR_L, "aff_read_random - offset: %" PRIuOFF " - len: %" PRIuOFF " - %s", tot_offset, len, strerror(errno)); tsk_errstr2[0] = '\0'; return -1; } aff_info->seek_pos += cnt; return cnt; }
static int affuse_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { int res = 0; (void) fi; if(strcmp(path, raw_path) != 0){ return -ENOENT; } /* TODO: change to sector aligned readings to write NULLs to bad * blocks... */ /* looks like af_seek never fails */ af_seek(af_image, (uint64_t)offset, SEEK_SET); errno = 0; res = af_read(af_image, (unsigned char *)buf, (int)size); if (res<0){ if (errno==0) errno=-EIO; else res = -errno; } return res; }
TSK_IMG_INFO * aff_open(const TSK_TCHAR * const images[], unsigned int a_ssize) { IMG_AFF_INFO *aff_info; TSK_IMG_INFO *img_info; int type; char *image; #ifdef TSK_WIN32 // convert wchar_t* image path to char* to conform to // the AFFLIB API UTF16 *utf16 = (UTF16 *)images[0]; size_t ilen = wcslen(utf16); size_t olen = ilen*4 + 1; UTF8 *utf8 = (UTF8 *) tsk_malloc(olen); image = (char *) utf8; if ( image == NULL ) return NULL; TSKConversionResult retval = tsk_UTF16toUTF8_lclorder( (const UTF16 **) &utf16, &utf16[ilen], &utf8, &utf8[olen], TSKlenientConversion ); *utf8 = '\0'; if (retval != TSKconversionOK) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_FS_UNICODE); tsk_error_set_errstr("aff_open file: %" PRIttocTSK ": Error converting path to UTF-8 %d\n", images[0], retval); free(image); return NULL; } utf8 = (UTF8 *) image; while ( *utf8 ) { if ( *utf8 > 127 ) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_FS_UNICODE); tsk_error_set_errstr("aff_open file: %" PRIttocTSK ": Non-Latin paths are not supported for AFF images\n", images[0]); free(image); return NULL; } utf8++; } #else image = (char *) tsk_malloc( strlen(images[0])+1 ); if ( image == NULL ) return NULL; strncpy(image, images[0], strlen(images[0])+1 ); #endif if ((aff_info = (IMG_AFF_INFO *) tsk_img_malloc(sizeof(IMG_AFF_INFO))) == NULL) { free(image); return NULL; } img_info = (TSK_IMG_INFO *) aff_info; img_info->read = aff_read; img_info->close = aff_close; img_info->imgstat = aff_imgstat; img_info->sector_size = 512; if (a_ssize) img_info->sector_size = a_ssize; type = af_identify_file_type(image, 1); if ((type == AF_IDENTIFY_ERR) || (type == AF_IDENTIFY_NOEXIST)) { if (tsk_verbose) { tsk_fprintf(stderr, "aff_open: Error determining type of file: %" PRIttocTSK "\n", images[0]); perror("aff_open"); } tsk_error_reset(); tsk_error_set_errno(TSK_ERR_IMG_OPEN); tsk_error_set_errstr("aff_open file: %" PRIttocTSK ": Error checking type", images[0]); tsk_img_free(aff_info); free(image); return NULL; } else if (type == AF_IDENTIFY_AFF) { img_info->itype = TSK_IMG_TYPE_AFF_AFF; } else if (type == AF_IDENTIFY_AFD) { img_info->itype = TSK_IMG_TYPE_AFF_AFD; } else if (type == AF_IDENTIFY_AFM) { img_info->itype = TSK_IMG_TYPE_AFF_AFM; } else { img_info->itype = TSK_IMG_TYPE_AFF_ANY; } aff_info->af_file = af_open(image, O_RDONLY | O_BINARY, 0); if (!aff_info->af_file) { // @@@ Need to check here if the open failed because of an incorrect password. tsk_error_reset(); tsk_error_set_errno(TSK_ERR_IMG_OPEN); tsk_error_set_errstr("aff_open file: %" PRIttocTSK ": Error opening - %s", images[0], strerror(errno)); tsk_img_free(aff_info); if (tsk_verbose) { tsk_fprintf(stderr, "Error opening AFF/AFD/AFM file\n"); perror("aff_open"); } free(image); return NULL; } // verify that a password was given and we can read encrypted data. if (af_cannot_decrypt(aff_info->af_file)) { tsk_error_reset(); tsk_error_set_errno(TSK_ERR_IMG_PASSWD); tsk_error_set_errstr("aff_open file: %" PRIttocTSK, images[0]); tsk_img_free(aff_info); if (tsk_verbose) { tsk_fprintf(stderr, "Error opening AFF/AFD/AFM file (incorrect password)\n"); } free(image); return NULL; } aff_info->type = type; img_info->size = af_imagesize(aff_info->af_file); af_seek(aff_info->af_file, 0, SEEK_SET); aff_info->seek_pos = 0; free(image); return img_info; }
void sparse_test() { printf("Sparse test...\n"); char buf[1024]; char fn[1024]; uint64_t mult = (uint64_t)3 * (uint64_t)1000000000; // 3GB in AFFILE *af = af_open(filename(fn,sizeof(fn),"sparse"),O_CREAT|O_RDWR|O_TRUNC,0666); af_enable_compression(af,opt_compression_type,opt_compression_level); af_set_maxsize(af,(int64_t)1024*1024*256); af_set_pagesize(af,1024*1024*16); for(u_int i=0;i<10;i++){ uint64_t pos = mult*i; memset(buf,0,sizeof(buf)); snprintf(buf,sizeof(buf),"This is at location=%"I64u"\n",pos); af_seek(af,pos,SEEK_SET); af_write(af,(unsigned char *)buf,sizeof(buf)); } /* Now verify */ for(u_int i=0;i<10;i++){ uint64_t pos = mult*i; uint64_t q; af_seek(af,pos,SEEK_SET); af_read(af,(unsigned char *)buf,sizeof(buf)); char *cc = strchr(buf,'='); if(!cc){ printf("Garbage read at location %"I64u"\n.",pos); exit(1); } if(sscanf(cc+1,"%"I64u,&q)!=1){ printf("Could not decode value at location %"I64u"(%s)\n",pos,cc+1); exit(1); } if(pos!=q){ printf("Wrong value at location %"I64u"; read %"I64u" in error.\n", pos,q); exit(1); } } /* Now seek to somewhere that no data has been written and see if we get 0s. */ memset(buf,'g',sizeof(buf)); af_seek(af,mult/2,SEEK_SET); ssize_t r = af_read(af,(unsigned char *)buf,sizeof(buf)); if(r!=sizeof(buf)){ err(1,"Tried to read %zd bytes at mult/2; got %zd bytes\n",sizeof(buf),r); } for(u_int i=0;i<sizeof(buf);i++){ if(buf[i]!=0) err(1,"data error; buf[%d]=%d\n",i,buf[i]); } /* Now try to read the last page in the file */ unsigned char big_buf[65536]; af_seek(af,9*mult,SEEK_SET); r = af_read(af,big_buf,sizeof(big_buf)); if(r!=sizeof(buf)){ errx(1,"Tried to read %zd bytes at the end of the file; got %zd bytes (should get %zd)", sizeof(big_buf),r,sizeof(buf)); } /* Now see if we can read past the end of the file */ af_seek(af,11*mult,SEEK_SET); r = af_read(af,(unsigned char *)buf,sizeof(buf)); if(r!=0) errx(1,"Tried to read past end of file; got %zd bytes (should get 0)",r); af_close(af); printf("\nSprase test passes.\n"); printf("=====================\n\n"); }
int random_read_test(int total_bytes,int data_page_size) { printf("\n\n\nrandom read test. filesize=%d, page_size=%d\n", total_bytes,data_page_size); /* Create a regular file and an AFF file */ printf("Creating random_contents.img and random_contents.%s, " "both with %d bytes of user data...\n", opt_ext,total_bytes); int fd = open("test_random_contents.img", O_CREAT|O_RDWR|O_TRUNC|O_BINARY,0666); if(fd<0) err(1,"fopen"); AFFILE *af = open_testfile("test_random_contents",1); /* Just write it out as one big write */ unsigned char *buf = (unsigned char *)malloc(total_bytes); unsigned char *buf2 = (unsigned char *)malloc(total_bytes); /* First half is random */ #ifdef HAVE_RAND_PSEUDO_BYTES RAND_pseudo_bytes(buf,total_bytes/2); #else for(int i=0;i<total_bytes/2;i++){ buf[i] = random(); } #endif /* Second half is a bit more predictable */ for(int i=total_bytes/2;i<total_bytes;i++){ buf[i] = ((i % 256) + (i / 256)) % 256; } if(write(fd,buf,total_bytes)!=total_bytes) err(1,"fwrite"); if(af_write(af,buf,total_bytes)!=(int)total_bytes) err(1,"af_write"); /* Now try lots of seeks and reads */ for(int i=0;i<MAX_FMTS;i++){ uint32_t loc = rand() % total_bytes; uint32_t len = rand() % total_bytes; memset(buf,0,total_bytes); memset(buf2,0,total_bytes); if(i%250==0) printf("\r#%d reading %"PRIu32" bytes at %"PRIu32" ...",i,loc,len); fflush(stdout); uint32_t l1 = (uint32_t)lseek(fd,loc,SEEK_SET); uint32_t l2 = (uint32_t)af_seek(af,loc,SEEK_SET); if(l1!=l2){ err(1,"l1 (%"PRIu32") != l2 (%"PRIu32")",l1,l2); } int r1 = read(fd,buf,len); int r2 = af_read(af,buf2,len); if(r1!=r2){ err(1,"r1 (%d) != r2 (%d)",r1,r2); } } af_close(af); close(fd); printf("\nRandom read test passes\n"); return 0; }
int random_write_test() { char buf[1024]; char *tally = (char *)calloc(MAX_FMTS,1); int i; memset(tally,0,sizeof(tally)); /* Create the AFF file */ sprintf(buf,fmt,0); // figure out how big fmt string is int fmt_size = strlen(buf); printf("Random write test...\n"); printf("Creating test file with %d byte records.\n", fmt_size); AFFILE *af = open_testfile("test_random",1); if(af_write(af,(unsigned char *)buf,fmt_size)!=fmt_size){ err(1,"af_write"); } for(i=0;i<MAX_FMTS;i++){ /* Find a random spot that's available */ int pos = rand() % MAX_FMTS; while(tally[pos]==1){ // if this one is used, find next pos = (pos + 1) % MAX_FMTS; } tally[pos] = 1; sprintf(buf,fmt,pos); assert((int)strlen(buf)==fmt_size); // make sure af_seek(af,fmt_size*pos,SEEK_SET); int wrote = af_write(af,(unsigned char *)buf,fmt_size); if(wrote !=fmt_size){ fprintf(stderr,"Attempt to write buffer #%d \n",pos); fprintf(stderr,"wrote %d bytes instead of %d bytes\n",wrote,fmt_size); exit(1); } if(i%250==0) printf("\r%d ...",i); fflush(stdout); } af_close(af); /* Now verify what was written */ printf("Verifying write test...\n"); af = open_testfile("test_random",0); for(i=0;i<MAX_FMTS;i++){ char should[256]; // what we should get sprintf(should,fmt,i); int got = af_read(af,(unsigned char *)buf,fmt_size); if(got != fmt_size){ fprintf(stderr,"Attempt to read %d bytes; got %d\n",fmt_size,got); exit(1); } if(i%250==24) printf("\r%d .. %d okay",i-24,i); } af_close(af); printf("\n"); printf("\nRandom write test passes.\n"); printf("======================\n"); return 0; }
IMG_INFO * aff_open(const char **images, IMG_INFO * next) { IMG_AFF_INFO *aff_info; IMG_INFO *img_info; int type; if (next != NULL) { tsk_errno = TSK_ERR_IMG_LAYERS; snprintf(tsk_errstr, TSK_ERRSTR_L, "AFF must be lowest layer"); tsk_errstr2[0] = '\0'; return NULL; } aff_info = (IMG_AFF_INFO *) mymalloc(sizeof(IMG_AFF_INFO)); if (aff_info == NULL) { return NULL; } memset((void *) aff_info, 0, sizeof(IMG_AFF_INFO)); img_info = (IMG_INFO *) aff_info; img_info->read_random = aff_read_random; img_info->get_size = aff_get_size; img_info->close = aff_close; img_info->imgstat = aff_imgstat; type = af_identify_type(images[0]); if ((type == AF_IDENTIFY_ERR) || (type == AF_IDENTIFY_NOEXIST)) { if (verbose) { fprintf(stderr, "aff_open: Error determining type of file: %s\n", images[0]); perror("aff_open"); } tsk_errno = TSK_ERR_IMG_OPEN; snprintf(tsk_errstr, TSK_ERRSTR_L, "aff_open file: %s: Error checking type", images[0]); tsk_errstr2[0] = '\0'; free(aff_info); return NULL; } else if (type == AF_IDENTIFY_AFF) { img_info->itype = AFF_AFF; } else if (type == AF_IDENTIFY_AFD) { img_info->itype = AFF_AFD; } else if (type == AF_IDENTIFY_AFM) { img_info->itype = AFF_AFM; } // else if ((type == AF_IDENTIFY_EVF) || (type ==AF_IDENTIFY_EVD )) { // img_info->itype = AFF_AFF; // } else { tsk_errno = TSK_ERR_IMG_MAGIC; snprintf(tsk_errstr, TSK_ERRSTR_L, "aff_open: Not an AFF, AFD, or AFM file"); tsk_errstr2[0] = '\0'; free(aff_info); if (verbose) fprintf(stderr, "Not an AFF/AFD/AFM file\n"); return NULL; } aff_info->af_file = af_open(images[0], O_RDONLY, 0); if (!aff_info->af_file) { tsk_errno = TSK_ERR_IMG_OPEN; snprintf(tsk_errstr, TSK_ERRSTR_L, "aff_open file: %s: Error opening - %s", images[0], strerror(errno)); tsk_errstr2[0] = '\0'; free(aff_info); if (verbose) { fprintf(stderr, "Error opening AFF/AFD/AFM file\n"); perror("aff_open"); } return NULL; } aff_info->type = type; img_info->size = af_imagesize(aff_info->af_file); af_seek(aff_info->af_file, 0, SEEK_SET); aff_info->seek_pos = 0; return img_info; }