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

📄 vnode_split_raw.cpp

📁 sleuthit-2.09 一个磁盘的工具集
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    vni->imagesize = af->image_size;    vni->pagesize  = af->image_pagesize;    vni->supports_compression = 0;    vni->supports_metadata    = 0;    vni->changable_pagesize   = 1;	// change it at any time    vni->changable_sectorsize = 1;	// change it at any time    return 0;}static int split_raw_read(AFFILE *af, unsigned char *buf, uint64 pos,size_t count){    struct split_raw_private *srp = SPLIT_RAW_PRIVATE(af);    off_t c3;    int ret = 0;				// how many bytes read    if ((af->image_size - pos) < (unsigned)count){	count = (off_t)(af->image_size - pos);    }    while (count > 0) {	int filenum = -1;	off_t file_offset = 0;		if (af->maxsize) {		// if we do file segments	    filenum     = (int)(pos / af->maxsize);	    file_offset = (off_t)(pos % af->maxsize);	} else {	    filenum     = 0;	    file_offset = (off_t)pos;	}	if (file_offset != (off_t) srp->pos[filenum]) {	    off_t c2 = lseek (srp->fds[filenum], file_offset, SEEK_SET);	    if (file_offset != c2) {	// seek failed; return work to date		if (ret) return ret;	// some bytes were read; return that		else return -1;		// no bytes read; return error	    }	    srp->pos[filenum] = c2;	// this file starts here	}	if (af->maxsize && ((af->maxsize - file_offset) < (unsigned) count))	    c3 = (off_t)(af->maxsize - file_offset);	else	    c3 = count;	off_t c4 = read (srp->fds[filenum], buf, c3);	if (c4 <= 0) {			// got an error	    if (ret)	return ret;		// return how many bytes we read	    else return -1;			// otherwise, return -1	}	buf += c4;	count -= c4;	ret += c4;	pos += c4;	srp->pos[filenum] += c4;	// position of this file pointer	if (c3 != c4) return ret;		// incomplete?    }    return ret;}/* * split_raw_write_internal2: * If buf==0, assume we are writing zeros to the end of the file, * and just seek to the last character and write a single NUL. */int split_raw_write_internal2(AFFILE *af, unsigned char *buf, uint64 pos,size_t count){    struct split_raw_private *srp = SPLIT_RAW_PRIVATE(af);    off_t c1, c3;    int i;    int ret = 0;    struct affcallback_info acbi;    /* Setup the callback structure */    memset(&acbi,0,sizeof(acbi));    acbi.info_version = 1;    acbi.af = af->parent ? af->parent : af;    acbi.pagenum = af->image_pagesize ? pos / af->image_pagesize : 0;    acbi.bytes_to_write = count;    while (count > 0) {	if (af->maxsize) {	// do we need to possibly split into multiple file writes?	    /* Figure out which file number we will need to write to... */	    if (pos >= (af->maxsize * srp->num_raw_files)) {		int fd = open(srp->next_raw_fname, O_RDWR | O_CREAT | O_EXCL | O_BINARY, 0666);		if (fd < 0) {		  (*af->error_reporter)("split_raw_write: open(%s): ",af->fname);		    if (ret) return ret;		    else return -1;		}		srp_add_fd(af,fd);		if (increment_fname (srp->next_raw_fname) != 0) {		  (*af->error_reporter)("split_raw_write: too many files\n");		    if (ret)			return ret;		    else			return -1;		}	    }	    i  = (int)(pos / af->maxsize);	    c1 = (off_t)(pos % af->maxsize);	} else {	    i = 0;	    c1 = (off_t)pos;	}	if (c1 != (off_t)srp->pos[i]) {	// do we need to seek this file?	    off_t c2 = lseek (srp->fds[i], c1, SEEK_SET); // try to seek	    if (c1 != c2) {		// hm. Ended up in the wrong place. That's an error		if (ret>0) {		// return how many bytes we got		    return ret;		}		else {		    return -1;		}	    }	    srp->pos[i] = c2;	}	if (af->maxsize && ((af->maxsize - c1) < (unsigned)count))	  c3 = (off_t)(af->maxsize - c1);	else	    c3 = count;	if(af->w_callback) {acbi.phase = 3;(*af->w_callback)(&acbi);}	/* WRITE THE DATA! */	off_t c4 = 0;	if(buf){	    c4 = write (srp->fds[i], buf, c3);	}	else {	    /* Extend with lseek() and write a single byte */	    char z = 0;	    lseek(srp->fds[i],c3-1,SEEK_CUR);	    write(srp->fds[i],&z,1);	    c4 = c3;	}	/* DONE! */	acbi.bytes_written = c4;	if(af->w_callback) {acbi.phase = 4;(*af->w_callback)(&acbi);} 	if (c4 <= 0) {			// some error writing?	    if (ret)		return ret;	    else		return -1;	}	buf   += c4;	count -= c4;	ret   += c4;	pos   += c4;	srp->pos[i] += c4;	if (af->image_size < pos) af->image_size = pos;	// image was extended	if (c3 != c4){			// amount written doesn't equal request; return 	    return ret;	}    }    return ret;}int split_raw_write(AFFILE *af, unsigned char *buf, uint64 pos,size_t count){  /* If we are being asked to start writing beyond the end of the file   * pad out the file (and possibly create one or more new image files.)   */  if (af->maxsize) {      if (pos > af->image_size) {        // writing beyond the end...	  while(pos > af->image_size){		      /* repeat until file is as big as where we should be writing */	      int64 bytes_left   = pos - af->image_size;	      int bytes_to_write = (int)(af->maxsize - (af->image_size % af->maxsize)); 	      if(bytes_to_write > bytes_left) bytes_to_write = (int)bytes_left;	      int bytes_written = split_raw_write_internal2(af,0,af->image_size,bytes_to_write); 	      if(bytes_to_write != bytes_written){		  return -1;		// some kind of internal error	      }	  }      }  }  return split_raw_write_internal2 (af, buf, pos,count);}/* Get a segment; if a data page is being asked for, then fake it. * Otherwise, return an error. */static int split_raw_get_seg(AFFILE *af,const char *name,unsigned long *arg,unsigned char *data,		       size_t *datalen){    int64 page_num = af_segname_page_number(name);    if(page_num<0){	errno = ENOTSUP;		// sorry! We don't store metadata	return -1;    }      uint64 pos = page_num * af->image_pagesize; // where we are to start reading    uint64 bytes_left = af->image_size - pos;	// how many bytes left in the file    unsigned int bytes_to_read = af->image_pagesize; // copy this many bytes, unless    if(bytes_to_read > bytes_left) bytes_to_read = (unsigned int)bytes_left; // only this much is left        if(arg) *arg = 0;			// arg is always 0    if(datalen){	if(*datalen==0 && data==0){ // asked for 0 bytes, so give the actual size	    *datalen = bytes_to_read;	    return 0;	}	if(*datalen < (unsigned)bytes_to_read){	    *datalen = bytes_to_read;	    return AF_ERROR_DATASMALL;	}    }    if(data){	unsigned bytes_read = split_raw_read(af,data,pos,bytes_to_read);	if(bytes_read==bytes_to_read){	    if(datalen) *datalen = bytes_read;	    return 0;	}	return -1;			// some kind of EOF?    }    return 0;				// no problems!}/* * split_raw_get_next_seg: * Try get_next_seg on the AFF file first. If that fails, * create the next virtual segment */static int split_raw_get_next_seg(AFFILE *af,char *segname,size_t segname_len,unsigned long *arg,				  unsigned char *data,size_t *datalen_){    struct split_raw_private *srp = SPLIT_RAW_PRIVATE(af);    int64 total_pages = (af->image_size + af->image_pagesize - 1) / af->image_pagesize;    if(srp->cur_page >= total_pages) return -1; // that's all there are    /* Make the segment name */    char pagename[AF_MAX_NAME_LEN];    memset(pagename,0,sizeof(pagename));    snprintf(pagename,sizeof(pagename),AF_PAGE,srp->cur_page++);    /* Get the segment, if we can */    int r = split_raw_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){	    strcpy(segname,pagename);	    return 0;	}	/* segname wasn't big enough */	return -2;    }    return r;				// some other error}/* Rewind all of the segments */static int split_raw_rewind_seg(AFFILE *af){    struct split_raw_private *srp = SPLIT_RAW_PRIVATE(af);    srp->cur_page = 0;    return 0;}static int split_raw_update_seg(AFFILE *af, const char *name,				unsigned long arg,const void *value,unsigned int vallen)    {    int64 page_num = af_segname_page_number(name);    if(page_num<0){	errno = ENOTSUP;		// sorry! We don't store metadata	return -1;    }	    uint64 pos = page_num * af->image_pagesize; // where we are to start reading    return split_raw_write(af, (unsigned char *)value, pos,vallen);}struct af_vnode vnode_split_raw = {    AF_IDENTIFY_SPLIT_RAW,    AF_VNODE_TYPE_COMPOUND|AF_VNODE_TYPE_RELIABLE|AF_VNODE_MAXSIZE_MULTIPLE,    "Split Raw",    split_raw_identify_file,    split_raw_open,    split_raw_close,    split_raw_vstat,    split_raw_get_seg,			// get seg    split_raw_get_next_seg,		// get_next_seg    split_raw_rewind_seg,		// rewind_seg    split_raw_update_seg,		// update_seg    0,					// del_seg    split_raw_read,			// read    split_raw_write			// write};

⌨️ 快捷键说明

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