📄 dtutil.c
字号:
* pcount gets the prefix string count verified. * Return value is Success or Failure. */intverify_prefix( struct dinfo *dip, u_char *buffer, size_t bcount, size_t *pcount ){ register u_char *bptr = buffer; register u_char *pstr = (u_char *)prefix_string; register size_t count; register int i; int status = SUCCESS; count = MIN(prefix_size, bcount); for (i = 0; (i < count); i++, bptr++, pstr++) { if (*bptr != *pstr) { size_t dump_size; ReportCompareError (dip, count, i, *pstr, *bptr); Fprintf ("Mismatch of data pattern prefix: '%s'\n", prefix_string); /* expected */ dump_size = CalculateDumpSize (prefix_size); dump_buffer (prefix_str, (u_char *)prefix_string, pstr, dump_size, prefix_size, TRUE); /* received */ dump_size = CalculateDumpSize (bcount); dump_buffer (data_str, buffer, bptr, dump_size, bcount, FALSE); status = FAILURE; break; } } *pcount = count; return (status);}/************************************************************************ * * * verify_buffers() - Verify Data Buffers. * * * * Description: * * Simple verification of two data buffers. * * * * Inputs: dip = The device information pointer. * * dbuffer = Data buffer to verify with. * * vbuffer = Verification buffer to use. * * count = The number of bytes to compare. * * * * Outputs: Returns SUCCESS/FAILURE = Data Ok/Compare Error. * * * ************************************************************************/intverify_buffers( struct dinfo *dip, u_char *dbuffer, u_char *vbuffer, size_t count ){ u_int32 i; u_char *dptr = dbuffer; u_char *vptr = vbuffer; for (i = 0; (i < count); i++, dptr++, vptr++) { if (*dptr != *vptr) { size_t dump_size = CalculateDumpSize (count); ReportCompareError (dip, count, i, *dptr, *vptr); /* expected */ dump_buffer (data_str, dbuffer, dptr, dump_size, count, TRUE); /* received */ dump_buffer (verify_str, vbuffer, vptr, dump_size, count, FALSE); return (FAILURE); } } return (SUCCESS);}intverify_lbdata( struct dinfo *dip, u_char *dbuffer, u_char *vbuffer, size_t count, u_int32 *lba ){ u_int32 i, dlbn, vlbn; u_char *dptr = dbuffer; u_char *vptr = vbuffer; int status = SUCCESS; for (i = 0; (i+sizeof(dlbn) < count); i += lbdata_size, dptr += lbdata_size, vptr += lbdata_size) { if (iot_pattern) { dlbn = get_lbn(dptr); vlbn = get_lbn(vptr); } else { dlbn = stoh (dptr, sizeof(dlbn)); vlbn = stoh (vptr, sizeof(vlbn)); } if (dlbn != vlbn) { size_t dump_size = CalculateDumpSize (count); ReportLbdataError(dip, *lba, count, i, dlbn, vlbn); /* expected */ dump_buffer (data_str, dbuffer, dptr, dump_size, count, TRUE); /* received */ dump_buffer (verify_str, vbuffer, vptr, dump_size, count, FALSE); status = FAILURE; break; } } *lba = (dlbn + 1); return (status);}/************************************************************************ * * * verify_data() - Verify Data Pattern. * * * * Description: * * If a pattern_buffer exists, then this data is used to compare * * the buffer instead of the pattern specified. * * * * Inputs: dip = The device information pointer. * * buffer = Pointer to data to verify. * * count = The number of bytes to compare. * * pattern = Data pattern to compare against. * * lba = Pointer to starting logical block address. * * * * Outputs: Returns SUCCESS/FAILURE = Data Ok/Compare Error. * * lba gets updated with the next lba to verify with. * * * ************************************************************************/intverify_data ( struct dinfo *dip, u_char *buffer, size_t count, u_int32 pattern, u_int32 *lba ){ bool check_lba = (iot_pattern || (lbdata_flag && lbdata_size)); /* * I hate to duplicate code, but the smaller functions * optimize better and give *much* better performance. */ if ( !check_lba && !prefix_string ) { return ( verify_data_normal(dip, buffer, count, pattern) ); } else if ( !check_lba && prefix_string ) { return ( verify_data_prefix(dip, buffer, count, pattern) ); } else { return ( verify_data_with_lba(dip, buffer, count, pattern, lba) ); }}static intverify_data_normal( struct dinfo *dip, u_char *buffer, size_t bcount, u_int32 pattern ){ register size_t i = 0; register u_char *vptr = buffer; register u_char *pptr = pattern_bufptr; register u_char *pend = pattern_bufend; register size_t count = bcount; bool error = FALSE; int status = SUCCESS; while ( (i < count) ) { if (*vptr != *pptr) { error = TRUE; ReportCompareError (dip, count, i, *pptr, *vptr); break; } else { i++, pptr++, vptr++; if (pptr == pend) pptr = pattern_buffer; } } if (error) { if (dump_flag) { size_t dump_size = CalculateDumpSize (count); if (pattern_buffer) { size_t pdump_size = (dump_size < patbuf_size) ? dump_size : patbuf_size; /* expected */ dump_buffer (pattern_str, pattern_buffer, pptr, pdump_size, patbuf_size, TRUE); } /* received */ dump_buffer (data_str, buffer, vptr, dump_size, count, FALSE); } status = FAILURE; } pattern_bufptr = pptr; return (status);}static intverify_data_prefix( struct dinfo *dip, u_char *buffer, size_t bcount, u_int32 pattern ){ register size_t i = 0; register u_char *vptr = buffer; register u_char *pptr = pattern_bufptr; register u_char *pend = pattern_bufend; register size_t count = bcount; bool error = FALSE; int status = SUCCESS; while ( (i < count) ) { /* * Verify the prefix string (if any). */ if (prefix_string && (i % lbdata_size) == 0) { size_t pcount; status = verify_prefix (dip, vptr, (count - i), &pcount); if (status == FAILURE) return (status); i += pcount; vptr += pcount; continue; } if (*vptr != *pptr) { error = TRUE; ReportCompareError (dip, count, i, *pptr, *vptr); break; } else { i++, pptr++, vptr++; if (pptr == pend) pptr = pattern_buffer; } } if (error) { if (dump_flag) { size_t dump_size = CalculateDumpSize (count); if (pattern_buffer) { size_t pdump_size = (dump_size < patbuf_size) ? dump_size : patbuf_size; /* expected */ dump_buffer (pattern_str, pattern_buffer, pptr, pdump_size, patbuf_size, TRUE); } /* received */ dump_buffer (data_str, buffer, vptr, dump_size, count, FALSE); } status = FAILURE; } pattern_bufptr = pptr; return (status);}static intverify_data_with_lba( struct dinfo *dip, u_char *buffer, size_t bcount, u_int32 pattern, u_int32 *lba ){ register size_t i = 0; register u_char *vptr = buffer; register u_char *pptr = pattern_bufptr; register u_char *pend = pattern_bufend; register size_t count = bcount; register u_int32 lbn, vlbn = *lba; bool error = FALSE; int status = SUCCESS; while ( (i < count) ) { /* * Handle IOT and Lbdata logical block checks first. */ if ( ((i % lbdata_size) == 0) ) { /* * Verify the prefix string prior to encoded lba's. */ if (prefix_string) { size_t pcount; status = verify_prefix (dip, vptr, (count - i), &pcount); if (status == FAILURE) return (status); vptr += pcount; if ( (i += pcount) == count) continue; } if ( (i+sizeof(lbn) <= count) ) { if (iot_pattern) { vlbn = get_lbn(pptr); lbn = get_lbn(vptr); } else { lbn = stoh (vptr, sizeof(lbn)); } if (lbn != vlbn) { error = TRUE; ReportLbdataError (dip, *lba, count, i, vlbn, lbn); break; } else { int size; vlbn++; i += sizeof(lbn); vptr += sizeof(lbn); /* Skip past pattern bytes, handling wrapping. */ size = sizeof(lbn); while (size--) { pptr++; if (pptr == pend) pptr = pattern_buffer; } } continue; } } if (*vptr != *pptr) { error = TRUE; ReportCompareError (dip, count, i, *pptr, *vptr); break; } else { i++, pptr++, vptr++; if (pptr == pend) pptr = pattern_buffer; } } if (error) { if (dump_flag) { size_t dump_size = CalculateDumpSize (count); if (pattern_buffer) { size_t pdump_size = (dump_size < patbuf_size) ? dump_size : patbuf_size; /* expected */ dump_buffer (pattern_str, pattern_buffer, pptr, pdump_size, patbuf_size, TRUE); } /* received */ dump_buffer (data_str, buffer, vptr, dump_size, count, FALSE); } status = FAILURE; } pattern_bufptr = pptr; *lba = vlbn; /* Pass updated lba back to caller. */ return (status);}/************************************************************************ * * * verify_padbytes() - Verify Pad Bytes Consistency. * * * * Description: * * This function simply checks the pad bytes to ensure they * * haven't been overwritten after a read operation. * * * * Inputs: dip = The device information pointer. * * buffer = Pointer to start of pad buffer. * * count = The last record read byte count. * * pattern = Data pattern to compare against. * * offset = Offset to where pad bytes start. * * * * Outputs: Returns SUCCESS/FAILURE = Data Ok/Compare Error. * * * ************************************************************************/intverify_padbytes ( struct dinfo *dip, u_char *buffer, size_t count, u_int32 pattern, size_t offset ){ size_t pbytes, pindex; int status; /* * For short reads, checks inverted data bytes & pad bytes. */ if ( (offset != count) && spad_check) { size_t resid = (offset - count); pindex = (count & (sizeof(u_int32) - 1)); pbytes = (resid < PADBUFR_SIZE) ? resid : PADBUFR_SIZE; status = dopad_verify (dip, buffer, count, pattern, pbytes, pindex, TRUE); if (status == FAILURE) return (status); } pindex = 0; pbytes = PADBUFR_SIZE; return (dopad_verify (dip, buffer, offset, pattern, pbytes, pindex, FALSE));}static intdopad_verify ( struct dinfo *dip, u_char *buffer, size_t offset, u_int32 pattern, size_t pbytes, size_t pindex, bool inverted ){ int status = SUCCESS; u_char *vptr; size_t i; union { u_char pat[sizeof(u_int32)]; u_int32 pattern; } p; p.pattern = pattern; vptr = buffer + offset; /* * NOTE: We could be comparing inverted data on short reads. */ for (i = pindex; i < (pbytes + pindex); i++, vptr++) { if (*vptr != p.pat[i & (sizeof(u_int32) - 1)]) { (void) RecordError(); Fprintf ( "Data compare error at %s byte %u in record number %lu\n", (inverted) ? "inverted" : "pad", (inverted) ? (offset + i) : i, (dip->di_records_read + 1)); ReportDeviceInfo (dip, offset, i, FALSE); Fprintf ("Data expected = %#x, data found = %#x, pattern = 0x%08x\n", p.pat[i & (sizeof(u_int32) - 1)], *vptr, pattern); if (dump_flag) { /* * Limit data dumped for short corrupted records. */ size_t dump_size = CalculateDumpSize (offset); dump_buffer (data_str, buffer, vptr, dump_size, data_size, FALSE); } else { Fprintf ("Data buffer pointer = %#lx, buffer offset = %ld\n", vptr, offset); } fflush (efp); status = FAILURE; break; } } return (status);}/************************************************************************ * * * process_pfile() - Process a pattern file. * * * * Inputs: fd = Pointer to file descriptor. * * file = Pointer to pattern file name. * * mode = The mode (read/write) for open. * * * * Outputs: Returns on success, exits on open failure. * * * * Return Value: * * Void. * * * ************************************************************************/voidprocess_pfile (int *fd, char *file, int mode){ struct stat sb; size_t count, size; u_char *buffer;#if defined(__WIN32__) mode |= O_BINARY;#endif /* defined(__WIN32__) */ if ( (*fd = open (file, mode)) == FAILURE) { Fprintf ("Error opening pattern file '%s', mode = %o\n", file, mode); report_error ("process_pfile", TRUE); exit (exit_status); } if (fstat (*fd, &sb) < 0) { report_error ("fstat", TRUE); exit (exit_status); } /* * Only support regular files at this time. */ if ((sb.st_mode & S_IFMT) != S_IFREG) { Fprintf ("Expect regular file for pattern file.\n"); exit (exit_status); } size = (size_t) sb.st_size; buffer = (u_char *) myalloc (size, 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -