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; }
int fix(const char *infile) { char buf[1024]; int flags = (opt_fix ? O_RDWR : O_RDONLY) | O_BINARY; switch(af_identify_file_type(infile,1)){ case AF_IDENTIFY_ERR: perror(infile); return 0; default: fprintf(stderr,"%s is not an AFF file\n",infile); return 0; case AF_IDENTIFY_AFF: break; } printf("%s ",infile); int r=0; /* First see if the if the file begins with an AFF flag */ int fd = open(infile,flags,0666); if(fd<0) err(1,"fopen(%s)",infile); if(read(fd,buf,strlen(AF_HEADER)+1)!=strlen(AF_HEADER)+1) err(1,"can't read AFF file header. Stop."); if(strcmp(buf,AF_HEADER)!=0) err(1,"%s does not begin with an AF_HEADER. Stop.",infile); if(read(fd,buf,strlen(AF_SEGHEAD)+1)!=strlen(AF_SEGHEAD)+1) err(1,"Can't read AF_SEGHEAD after AF_HEADER. Stop."); if(strcmp(buf,AF_SEGHEAD)!=0) err(1,"%s does not have an AF_SEGHEAD after AF_SEGEADER. Stop.",infile); /* Figure out length */ off_t len = lseek(fd,0,SEEK_END); if(len<0) err(1,"Can't seek to end of %s. Stop.",infile); close(fd); AFFILE *af = af_open_with(infile,AF_HALF_OPEN|flags,0,&vnode_aff); printf("Scanning AFF file...\n"); r = (*af->v->open)(af); /* See if we can build a TOC */ if(r<0){ printf("AFF file corrupt at %"I64d" out of %"I64d" (%"I64d" bytes from end)\n", ftello(af->aseg),(int64_t)len,len-ftello(af->aseg)); if(opt_fix){ printf("Truncating... %d \n",fileno(af->aseg)); if(ftruncate(fileno(af->aseg),ftello(af->aseg))){ err(1,"ftruncate"); } } } /* See if it has a GID or an encrypted GID */ if(af_get_seg(af,AF_IMAGE_GID,0,0,0)!=0 && af_get_seg(af,AF_IMAGE_GID AF_AES256_SUFFIX,0,0,0)!=0){ printf("AFF file is missing a GID. "); if(opt_fix){ printf("Making one..."); if(af_make_gid(af)<0) af_err(1,"af_make_gid"); } putchar('\n'); } af_close(af); return 0; }