⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 afflib_pages.cpp

📁 sleuthit-2.09 一个磁盘的工具集
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* * The AFFLIB page abstraction. *//* * Copyright (c) 2005, 2006 *	Simson L. Garfinkel and Basis Technology, Inc.  *      All rights reserved. * * This code is derrived from software contributed by * Simson L. Garfinkel * * 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. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *    This product includes software developed by Simson L. Garfinkel *    and Basis Technology Corp. * 4. Neither the name of Simson Garfinkel, Basis Technology, or other *    contributors to this program may be used to endorse or promote *    products derived from this software without specific prior written *    permission. * * THIS SOFTWARE IS PROVIDED BY SIMSON GARFINKEL, BASIS TECHNOLOGY, * 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 SIMSON GARFINKEL, BAIS TECHNOLOGy, * 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 "config.h"#include "afflib.h"#include "afflib_i.h"/* af_read_sizes: * Get the page sizes if they are set in the file. */void af_read_sizes(AFFILE *af){    if(af_get_seg(af,AF_PAGESIZE,&af->image_pagesize,0,0)){	af_get_seg(af,AF_SEGSIZE_D,&af->image_pagesize,0,0); // try old name    }    if(af_get_segq(af,AF_IMAGESIZE,(int64 *)&af->image_size)){	/* Need to recover the image size */	char segname[AF_MAX_NAME_LEN];	unsigned long arg;	size_t datalen = 0;	af_rewind_seg(af);		//  start at the beginning	int64 highest_page = -1;	while(af_get_next_seg(af,segname,sizeof(segname),&arg,0,&datalen)==0){	    if(segname[0]==0) continue;	// ignore sector	    int64 pagenum = af_segname_page_number(segname);	    if(pagenum > highest_page) highest_page = pagenum;	}	af->image_size = af->image_pagesize * (highest_page+1);    }	    af->image_size_in_file = af->image_size;    af_get_seg(af,AF_SECTORSIZE,&af->image_sectorsize,0,0);    if(af->image_sectorsize==0) af->image_sectorsize = 512; // reasonable default    size_t sectorsize = af->image_sectorsize;    if(af->badflag==0) af->badflag = (unsigned char *)malloc(sectorsize);    if(af_get_seg(af,AF_BADFLAG,0,af->badflag,(size_t *)&sectorsize)==0){	af->badflag_set = 1;    }}int af_page_size(AFFILE *af){    return af->image_pagesize;}/* af_set_sectorsize: * Sets the sectorsize. * Fails with -1 if imagesize >=0 unless these changes permitted */int af_set_sectorsize(AFFILE *af,int sectorsize){    struct af_vnode_info vni;    af_vstat(af,&vni);    if(vni.changable_pagesize==0 && af->image_size>0){	errno = EINVAL;	return -1;    }    af->image_sectorsize =sectorsize;    if(af->badflag==0) af->badflag = (unsigned char *)malloc(sectorsize);    else af->badflag = (unsigned char *)realloc(af->badflag,sectorsize);    af->badflag_set = 0;    if(af_update_seg(af,AF_SECTORSIZE,sectorsize,0,0)){	if(errno != ENOTSUP) return -1;    }    return 0;}/* * af_set_pagesize: * Sets the pagesize. Fails with -1 if it can't be changed. */int af_set_pagesize(AFFILE *af,long pagesize){    /* Allow the pagesize to be changed if it hasn't been set yet     * and if this format doesn't support metadata updating (which is the raw formats)     */    struct af_vnode_info vni;    af_vstat(af,&vni);    if(vni.changable_pagesize==0 && af->image_size>0){	if(pagesize==af->image_pagesize) return 0; // it's already set to this, so let it pass	errno = EINVAL;	return -1;    }    if(pagesize % af->image_sectorsize != 0){	(*af->error_reporter)("Cannot set pagesize to %d (sectorsize=%d)\n",			      pagesize,af->image_sectorsize);	errno = EINVAL;	return -1;    }    af->image_pagesize = pagesize;    if(af_update_seg(af,AF_PAGESIZE,pagesize,0,0)){	if(errno != ENOTSUP) return -1;	// error updating (don't report ENOTSUP);    }    return 0;}/**************************************************************** *** page-level interface ****************************************************************/int af_get_page_raw(AFFILE *af,int64 pagenum,unsigned long *arg,		    unsigned char *data,size_t *bytes){    char segname[AF_MAX_NAME_LEN];        memset(segname,0,sizeof(segname));    sprintf(segname,AF_PAGE,pagenum);    int r = af_get_seg(af,segname,arg,data,bytes);    if(r!=0){	/* Couldn't read with AF_PAGE; try AF_SEG_D */	sprintf(segname,AF_SEG_D,pagenum);	r = af_get_seg(af,segname,arg,data,bytes);    }    if(r==0 && bytes && *bytes>0) af->pages_read++; // note that we read a page    return r;}/* af_get_page: * Get a page from its named segment. * If the page is compressed, uncompress it. * data points to a segmenet of at least *bytes; * *bytes is then modified to indicate the actual amount of bytes read. * if shouldfree is set, then data should be freed. * Return 0 if success, -1 if fail. */int af_get_page(AFFILE *af,int64 pagenum,unsigned char *data,size_t *bytes){    unsigned long arg=0;    size_t page_len=0;    if (af_trace) fprintf(af_trace,"af_get_page(%p,pagenum=%"I64d",buf=%p,bytes=%d)\n",af,pagenum,data,bytes);    /* Find out the size of the segment and if it is compressed or not.     * If we can't find it with new nomenclature, try the old one...     */    if(af_get_page_raw(af,pagenum,&arg,0,&page_len)){	/* Segment doesn't exist.	 * If we have been provided with a buffer, fill buffer with the 'bad segment' flag and return.	 */	if (data) {	    for(size_t i = 0;i <= af->image_pagesize - af->image_sectorsize;		i+= af->image_sectorsize){		memcpy(data+i,af->badflag,af->image_sectorsize);		af->bytes_memcpy += af->image_sectorsize;	    }	}	return -1;			// segment doesn't exist    }           /* If no data buffer was provided, just return */    if(data==0) return 0;    /* If the segment isn't compressed, just get it*/    unsigned long pageflag = 0;    if((arg & AF_PAGE_COMPRESSED)==0){	int ret = af_get_page_raw(af,pagenum,&pageflag,data,bytes);	if(*bytes > page_len) *bytes = page_len; // we only read this much	if(ret!=0) return ret;		// some error happened?    }    else {	/* Allocate memory to hold the compressed segment */	unsigned char *compressed_data = (unsigned char *)malloc(page_len);	size_t compressed_data_len = page_len;	if(compressed_data==0){	    return -2;			// memory error	}	/* Get the data */	if(af_get_page_raw(af,pagenum,&pageflag,compressed_data,&compressed_data_len)){	    free(compressed_data);	    return -3;			// read error	}	/* Now uncompress directly into the buffer provided by the caller. */	int res = -1;			// 0 is success	switch((pageflag & AF_PAGE_COMP_ALG_MASK)){	case AF_PAGE_COMP_ALG_ZERO:	    if(compressed_data_len != 4){		(*af->error_reporter)("ALG_ZERO compressed data is %d bytes, expected 4.",compressed_data_len);		break;	    }	    memset(data,0,af->image_pagesize);	    *bytes = ntohl(*(long *)compressed_data);	    res = 0;			// not very hard to decompress with the ZERO compressor.	    break;	case AF_PAGE_COMP_ALG_ZLIB:	    res = uncompress(data,(uLongf *)bytes,compressed_data,compressed_data_len);	    switch(res){	    case Z_OK:		break;	    case Z_ERRNO:		(*af->error_reporter)("Z_ERRNOR decompressing segment %"I64d,pagenum);	    case Z_STREAM_ERROR:		(*af->error_reporter)("Z_STREAM_ERROR decompressing segment %"I64d,pagenum);	    case Z_DATA_ERROR:		(*af->error_reporter)("Z_DATA_ERROR decompressing segment %"I64d,pagenum);	    case Z_MEM_ERROR:		(*af->error_reporter)("Z_MEM_ERROR decompressing segment %"I64d,pagenum);	    case Z_BUF_ERROR:		(*af->error_reporter)("Z_BUF_ERROR decompressing segment %"I64d,pagenum);	    case Z_VERSION_ERROR:		(*af->error_reporter)("Z_VERSION_ERROR decompressing segment %"I64d,pagenum);	    default:		(*af->error_reporter)("uncompress returned an invalid value in get_segment");	    }	    break;#ifdef USE_LZMA	case AF_PAGE_COMP_ALG_LZMA:	    res = lzma_uncompress(data,bytes,compressed_data,compressed_data_len);	    if (af_trace) fprintf(af_trace,"   LZMA decompressed page %"I64d". %d bytes => %d bytes\n",				  pagenum,compressed_data_len,*bytes);	    switch(res){	    case 0:break;		// OK	    case 1:(*af->error_reporter)("LZMA header error decompressing segment %"I64d"\n",pagenum);		break;	    case 2:(*af->error_reporter)("LZMA memory error decompressing segment %"I64d"\n",pagenum);		break;	    }	    break;#endif	    	default:	    (*af->error_reporter)("Unknown compression algorithm 0x%d",				  pageflag & AF_PAGE_COMP_ALG_MASK);	    break;	}	free(compressed_data);		// don't need this one anymore	af->pages_decompressed++;	if(res!=Z_OK) return -1;    }    /* If the page size is larger than the sector_size,     * make sure that the rest of the sector is zeroed, and that the     * rest after that has the 'bad block' notation.     */    if(af->image_pagesize > af->image_sectorsize){	const int SECTOR_SIZE = af->image_sectorsize;	// for ease of typing	size_t bytes_left_in_sector = (SECTOR_SIZE - (*bytes % SECTOR_SIZE)) % SECTOR_SIZE;	for(size_t i=0;i<bytes_left_in_sector;i++){	    data[*bytes + i] = 0;	}	size_t end_of_data = *bytes + bytes_left_in_sector;		/* Now fill to the end of the page... */	for(size_t i = end_of_data; i <= af->image_pagesize-SECTOR_SIZE; i+=SECTOR_SIZE){	    memcpy(data+i,af->badflag,SECTOR_SIZE);	    af->bytes_memcpy += SECTOR_SIZE;	}    }    return 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -