📄 img_io.c
字号:
/* * Brian Carrier [carrier <at> sleuthkit [dot] org] * Copyright (c) 2008 Brian Carrier. All Rights reserved * * This software is distributed under the Common Public License 1.0 *//** * \file img_io.c * Contains the basic img reading API redirection functions. */#include "tsk_img_i.h"/** * \ingroup imglib * Reads data from an open disk image * @param a_img_info Disk image to read from * @param a_off Byte offset to start reading from * @param a_buf Buffer to read into * @param a_len Number of bytes to read into buffer * @returns -1 on error or number of bytes read */ssize_ttsk_img_read(TSK_IMG_INFO * a_img_info, TSK_OFF_T a_off, char *a_buf, size_t a_len){#define CACHE_AGE 1000 ssize_t retval = 0; int i; int cache_next = 0; // index to lowest age cache (to use next) size_t len2; if (a_img_info == NULL) { tsk_error_reset(); tsk_errno = TSK_ERR_IMG_ARG; snprintf(tsk_errstr, TSK_ERRSTR_L, "tsk_img_read: pointer is NULL"); return -1; } // if they ask for more than the cache length, skip the cache if (a_len > TSK_IMG_INFO_CACHE_LEN) { return a_img_info->read(a_img_info, a_off, a_buf, a_len); } /* See if the requested length is going to be too long. * we'll use this length when checking the cache. */ len2 = a_len; if (a_off + len2 > a_img_info->size) len2 = (size_t)(a_img_info->size - a_off); // check if it is in the cache for (i = 0; i < TSK_IMG_INFO_CACHE_NUM; i++) { // Look into the in-use cache entries if (a_img_info->cache_len[i] > 0) { // the retval check makes sure we don't go back in after data was read if ((retval == 0) && (a_img_info->cache_off[i] <= a_off) && (a_img_info->cache_off[i] + a_img_info->cache_len[i] >= a_off + len2)) { if (tsk_verbose) fprintf(stderr, "tsk_img_read: Read found in cache %d\n", i); // We found it... memcpy(a_buf, &a_img_info->cache[i][a_off - a_img_info->cache_off[i]], len2); retval = (ssize_t)len2; // reset its "age" since it was useful a_img_info->cache_age[i] = CACHE_AGE; // we don't break out of the loop so that we update all ages } else { /* decrease its "age" since it was not useful. * We don't let used ones go below 1 so that they are not * confused with entries that have never been used. */ a_img_info->cache_age[i]--; // see if this is the most eligible replacement if ((a_img_info->cache_len[cache_next] > 0) && (a_img_info->cache_age[i] < a_img_info->cache_age[cache_next])) cache_next = i; } } else { cache_next = i; } } // if we didn't find it, then load it into the cache_next entry if (retval == 0) { size_t rlen; // round the offset down to a sector boundary a_img_info->cache_off[cache_next] = (a_off / 512) * 512; if (tsk_verbose) fprintf(stderr, "tsk_img_read: Loading data into cache %d (%" PRIuOFF ")\n", cache_next, a_img_info->cache_off[cache_next]); // figure out the length to read into the cache rlen = TSK_IMG_INFO_CACHE_LEN; if (a_img_info->cache_off[cache_next] + rlen > a_img_info->size) { rlen = (size_t)(a_img_info->size - a_img_info->cache_off[cache_next]); } retval = a_img_info->read(a_img_info, a_img_info->cache_off[cache_next], a_img_info->cache[cache_next], rlen); // if no error, then set the variables and copy the data if (retval != -1) { a_img_info->cache_age[cache_next] = CACHE_AGE; a_img_info->cache_len[cache_next] = retval; // update the length we can actually copy (in case we did not get to read all that we wanted) if (a_off + len2 > a_img_info->cache_off[cache_next] + retval) len2 = (size_t)(a_img_info->cache_off[cache_next] + retval - a_off); memcpy(a_buf, &a_img_info->cache[cache_next][a_off - a_img_info->cache_off[cache_next]], len2); retval = (ssize_t)len2; } else { a_img_info->cache_len[cache_next] = 0; a_img_info->cache_age[cache_next] = 0; a_img_info->cache_off[cache_next] = 0; } } return retval;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -