static int mbox_write_verify(struct sbd_context *st, int mbox, struct sector_mbox_s *s_mbox) { void *data; int rc = 0; if (sector_write(st, MBOX_TO_SECTOR(mbox), s_mbox) < 0) return -1; data = sector_alloc(); if (sector_read(st, MBOX_TO_SECTOR(mbox), data) < 0) { rc = -1; goto out; } if (memcmp(s_mbox, data, sector_size) != 0) { cl_log(LOG_ERR, "Write verification failed!"); rc = -1; goto out; } rc = 0; out: free(data); return rc; }
/** * Read logpack header sector from log device. * * @fd log device fd opened. * @super_sectp super sector. * @lsid logpack lsid to read. * @logh_sect buffer to store logpack header data. * This allocated size must be sector size. * @salt log checksum salt. * * RETURN: * ture in success, or false. */ bool read_logpack_header_from_wldev( int fd, const struct walb_super_sector* super_sectp, u64 lsid, u32 salt, struct sector_data *logh_sect) { /* calc offset in the ring buffer */ u64 ring_buffer_offset = get_ring_buffer_offset_2(super_sectp); u64 ring_buffer_size = super_sectp->ring_buffer_size; u64 off = ring_buffer_offset + lsid % ring_buffer_size; struct walb_logpack_header *logh = get_logpack_header(logh_sect); /* read sector */ if (!sector_read(fd, off, logh_sect)) { LOGe("read logpack header (lsid %"PRIu64") failed.\n", lsid); return false; } /* check lsid */ if (lsid != logh->logpack_lsid) { LOGe("lsid (given %"PRIu64" read %"PRIu64") is invalid.\n", lsid, logh->logpack_lsid); return false; } if (!is_valid_logpack_header_with_checksum( logh, super_sectp->physical_bs, salt)) { LOGe("check logpack header failed.\n"); return false; } return true; }
/** * Read super sector. * * Currently 2nd super sector is not read. * * RETURN: * true in success, or false. */ bool read_super_sector(int fd, struct sector_data *sect) { u64 off0; if (!is_valid_sector_data(sect)) { LOGe("Sector data is not valid.\n"); return false; } ASSERT(sect->size <= PAGE_SIZE); off0 = get_super_sector0_offset(sect->size); if (!sector_read(fd, off0, sect)) { LOGe("Read sector failed.\n"); return false; } if (checksum(sect->data, sect->size, 0) != 0) { LOGe("Checksum invalid.\n"); return false; } if (!is_valid_super_sector(sect)) { LOGe("Super sector invalid.\n"); return false; } return true; }
bool sector_read_n(void *self, uint8_t *buf, daddr_t sector, int count) { int i; for (i = 0; i < count; i++) { if (!sector_read(self, buf, sector)) return false; buf += DEV_BSIZE; sector++; } return true; }
/*-----------------------------------------------------------*/ UINT8_T ReadBlockLink(UINT8_T index , BlockLink *bl) { UINT16_T crc; UINT8_T *buf; UINT8_T i; UINT8_T err=ERR_OK; buf=(UINT8_T*)local_malloc(sl->sector[index].bl_size); if(buf==NULL) return ERR_LOCAL_MALLOC; err=sector_read(index, bl->pxCurrentAddr, (void*)buf, sl->sector[index].bl_size); if(err!=ERR_OK) goto exit; //проверка CRC если требуется if((sl->sector[index].Type & SECTOR_CRC)>0) { Crc16_Clear(); i=sl->sector[index].StartAddrLen + sl->sector[index].SectorSizeLen; //размер структуры BlockLink crc=Crc16(buf,i); err=memcmp((void*)(buf+i),(void*)&crc,sizeof(UINT16_T)); if(err!=0x00) { err=ERR_CRC; goto exit; } } //загружаем в структуру i=sl->sector[index].StartAddrLen; bl->body.pxNextFreeBlock=0; memcpy((void*)&bl->body.pxNextFreeBlock,(void*)buf,i); bl->body.xBlockSize=0; memcpy((void*)&bl->body.xBlockSize,(void*)(buf+i),sl->sector[index].SectorSizeLen); exit: local_free(buf); return err; }
static int header_read(struct sbd_context *st, struct sector_header_s *s_header) { if (sector_read(st, 0, s_header) < 0) return -1; s_header->sector_size = ntohl(s_header->sector_size); s_header->timeout_watchdog = ntohl(s_header->timeout_watchdog); s_header->timeout_allocate = ntohl(s_header->timeout_allocate); s_header->timeout_loop = ntohl(s_header->timeout_loop); s_header->timeout_msgwait = ntohl(s_header->timeout_msgwait); /* This sets the global defaults: */ timeout_watchdog = s_header->timeout_watchdog; timeout_allocate = s_header->timeout_allocate; timeout_loop = s_header->timeout_loop; timeout_msgwait = s_header->timeout_msgwait; return 0; }
// Read next sector of stream void ole2_bufread(OLE2Stream* olest) { BYTE *ptr; assert(olest); assert(olest->ole); if ((DWORD)olest->fatpos!=ENDOFCHAIN) { if(olest->sfat) { assert(olest->ole->SSAT); assert(olest->buf); assert(olest->ole->SSecID); ptr = olest->ole->SSAT + olest->fatpos*olest->ole->lssector; memcpy(olest->buf, ptr, olest->bufsize); olest->fatpos=xlsIntVal(olest->ole->SSecID[olest->fatpos]); olest->pos=0; olest->cfat++; } else { assert(olest->fatpos >= 0); //printf("fatpos: %d max=%u\n",olest->fatpos, (olest->ole->cfat*olest->ole->lsector)/4); if(olest->fatpos > (olest->ole->cfat*olest->ole->lsector)/4) exit(-1); #if 0 // TODO: remove fseek(olest->ole->file,olest->fatpos*olest->ole->lsector+512,0); ret = fread(olest->buf,1,olest->bufsize,olest->ole->file); assert(ret == olest->bufsize); #endif assert((int)olest->fatpos >= 0); sector_read(olest->ole, olest->buf, olest->fatpos); //printf("Fat val: %d[0x%X]\n",olest->fatpos,olest->ole->SecID[olest->fatpos], olest->ole->SecID[olest->fatpos]); olest->fatpos=xlsIntVal(olest->ole->SecID[olest->fatpos]); olest->pos=0; olest->cfat++; } } // else printf("ENDOFCHAIN!!!\n"); }
/** * Read multiple sectors data at an offset. * * RETURN: * true in success, or false. */ bool sector_array_pread( int fd, u64 offset, struct sector_data_array *sect_ary, unsigned int start_idx, unsigned int n_sectors) { unsigned int i; ASSERT(fd > 0); ASSERT_SECTOR_DATA_ARRAY(sect_ary); ASSERT(start_idx + n_sectors <= sect_ary->size); for (i = 0; i < n_sectors; i++) { unsigned int idx = start_idx + i; u64 off = offset + i; bool ret = sector_read(fd, off, get_sector_data_in_array(sect_ary, idx)); if (!ret) { LOGe("read failed.\n"); return false; } } return true; }
// Read MSAT static size_t read_MSAT(OLE2* ole2, OLE2Header* oleh) { int sectorNum; // reconstitution of the MSAT ole2->SecID=malloc(ole2->cfat*ole2->lsector); // read first 109 sectors of MSAT from header { int count; count = (ole2->cfat < 109) ? ole2->cfat : 109; for (sectorNum = 0; sectorNum < count; sectorNum++) { assert(sectorNum >= 0); sector_read(ole2, (BYTE*)(ole2->SecID)+sectorNum*ole2->lsector, oleh->MSAT[sectorNum]); } } // Add additionnal sectors of the MSAT { DWORD sid = ole2->difstart; BYTE *sector = malloc(ole2->lsector); //printf("sid=%u (0x%x) sector=%u\n", sid, sid, ole2->lsector); while (sid != ENDOFCHAIN && sid != FREESECT) // FREESECT only here due to an actual file that requires it (old Apple Numbers bug) { int posInSector; // read MSAT sector sector_read(ole2, sector, sid); // read content for (posInSector = 0; posInSector < (ole2->lsector-4)/4; posInSector++) { DWORD s = *(DWORD_UA *)(sector + posInSector*4); //printf(" s[%d]=%d (0x%x)\n", posInSector, s, s); if (s != FREESECT) { sector_read(ole2, (BYTE*)(ole2->SecID)+sectorNum*ole2->lsector, s); sectorNum++; } } sid = *(DWORD_UA *)(sector + posInSector*4); //printf(" s[%d]=%d (0x%x)\n", posInSector, sid, sid); } free(sector); } #ifdef OLE_DEBUG if(xls_debug) { //printf("==== READ IN SECTORS FOR MSAT TABLE====\n"); int i; for(i=0; i<512/4; ++i) { // just the first block if(ole2->SecID[i] != FREESECT) printf("SecID[%d]=%d\n", i, ole2->SecID[i]); } } //exit(0); #endif // read in short table if(ole2->sfatstart != ENDOFCHAIN) { DWORD sector, k; BYTE *wptr; ole2->SSecID = (DWORD *)malloc(ole2->csfat*ole2->lsector); sector = ole2->sfatstart; wptr=(BYTE*)ole2->SSecID; for(k=0; k<ole2->csfat; ++k) { assert(sector != ENDOFCHAIN); fseek(ole2->file,sector*ole2->lsector+512,0); fread(wptr,1,ole2->lsector,ole2->file); wptr += ole2->lsector; sector = ole2->SecID[sector]; } #ifdef OLE_DEBUG if(xls_debug) { int i; for(i=0; i<512/4; ++i) { if(ole2->SSecID[i] != FREESECT) printf("SSecID[%d]=%d\n", i, ole2->SSecID[i]); } } #endif } return 0; }
int main( int argc, char **argv ) { int sector_size = 2048, mode = 1; long image_length, remaining_length, progress, last_pos, start_lba, i; char lba_parameter = 0; char destfname[256]; char string[256]; char buffer[4096]; struct opts_s opts = { false, false, false, false, false }; FILE *fsource, *fdest, *fboot, *fheader; printf("ISO LBA fixer 1.3 - (C) 2001 by DeXT\n\n"); // process command line strcpy(destfname,"fixed.iso"); if (argc < 2) opts.askforimage = true; else { for (i = 1; i < argc; i++) { if (atol(argv[i]) <= 0) // not a number, or negative one { if (!stricmp(argv[i], "/boot")) { opts.extractbootonly = true; if (i == 1) opts.askforimage = true; } else if (!stricmp(argv[i], "/header")) { opts.extractheaderonly = true; if (i == 1) opts.askforimage = true; } else if (!stricmp(argv[i], "/mac")) { opts.macformat = true; if (i == 1) opts.askforimage = true; } else if (!stricmp(argv[i], "/iso")) { opts.isoformat = true; if (i == 1) opts.askforimage = true; } else { if (i == 1) strcpy(string, argv[i]); else strcpy(destfname, argv[i]); } } else lba_parameter = i; } } if (opts.askforimage == true) { printf("\nPlease enter name of image to fix (Return to exit): "); gets(string); if (strlen(string) == 0) exit(1); } printf("Processing file: '%s'\n",string); fsource = fopen(string,"rb"); if (fsource == NULL) { printf("Image not found!"); exit(1); } fseek(fsource, 0L, SEEK_END); image_length = ftell(fsource); fseek(fsource, 0L, SEEK_SET); // detect format printf("Scanning image...\n"); fread(buffer, 1, 16, fsource); if (!memcmp(SYNC_DATA, buffer, 12)) // raw (2352) { sector_size = 2352; switch(buffer[15]) { case 2: mode = 2; break; case 1: mode = 1; break; default: { printf("Unsupported track mode (%d)", buffer[15]); exit (1); } } if (seek_pvd(buffer, 2352, mode, fsource) == 0) { printf("Could not find PVD!\n"); exit(1); } } else if (seek_pvd(buffer, 2048, 1, fsource)) { sector_size = 2048; mode = 1; } else if (seek_pvd(buffer, 2336, 2, fsource)) { sector_size = 2336; mode = 2; } else if (seek_pvd(buffer, 2056, 2, fsource)) { sector_size = 2056; mode = 2; opts.macformat = true; } else { printf("Could not find PVD!\n"); exit(1); } if (opts.isoformat == true) opts.macformat = false; printf("sector size = %d, mode = %d\n", sector_size, mode); if (opts.extractbootonly == false && opts.extractheaderonly == false) { if (lba_parameter != 0) start_lba = atol(argv[lba_parameter]); else { printf("\nPlease enter starting LBA value: "); gets(string); start_lba = atol(string); if (start_lba <= 0) { printf("Bad LBA value"); exit(1); } } printf("Creating destination file '%s'...\n",destfname); fdest = fopen(destfname, "wb"); if (fdest == NULL) { printf("Can't open destination file!"); exit(1); } } if (opts.extractheaderonly == false || (opts.extractheaderonly == true && opts.extractbootonly == true)) { printf("Saving boot area to file 'bootfile.bin'...\n"); fboot = fopen("bootfile.bin", "wb"); } if (opts.extractbootonly == false || (opts.extractheaderonly == true && opts.extractbootonly == true)) { printf("Saving ISO header to file 'header.iso'...\n"); fheader = fopen("header.iso", "wb"); } // save boot area fseek(fsource, 0L, SEEK_SET); for (i = 0; i < 16 ; i++) { sector_read(buffer, sector_size, mode, fsource); if (opts.extractbootonly == false && opts.extractheaderonly == false) { if (opts.macformat == true) fwrite (SUB_HEADER, 8, 1, fdest); fwrite(buffer, 2048, 1, fdest); } if (opts.extractheaderonly == false || (opts.extractheaderonly == true && opts.extractbootonly == true)) { if (opts.macformat == true) fwrite (SUB_HEADER, 8, 1, fboot); fwrite(buffer, 2048, 1, fboot); } if (opts.extractbootonly == false || (opts.extractheaderonly == true && opts.extractbootonly == true)) { if (opts.macformat == true) fwrite (SUB_HEADER, 8, 1, fheader); fwrite(buffer, 2048, 1, fheader); } } if (opts.extractheaderonly == false || (opts.extractheaderonly == true && opts.extractbootonly == true)) fclose(fboot); if (opts.extractbootonly == true && opts.extractheaderonly == false) exit(0); // boot saved, exit // seek & copy pvd etc. last_pos = ftell(fsource); // start of pvd do { sector_read(buffer, sector_size, mode, fsource); if (!memcmp(PVD_STRING, buffer, 8)) { printf("Found PVD at sector %ld\n", last_pos/sector_size); } else if (!memcmp(SVD_STRING, buffer, 8)) { printf("Found SVD at sector %ld\n", last_pos/sector_size); } else if (!memcmp(VDT_STRING, buffer, 8)) { printf("Found VDT at sector %ld\n", last_pos/sector_size); opts.last_vd = true; } else { printf("Error: Found unknown Volume Descriptor"); exit(1); } if (opts.extractbootonly == false && opts.extractheaderonly == false) { if (opts.macformat == true) fwrite (SUB_HEADER, 8, 1, fdest); fwrite(buffer, 2048, 1, fdest); } if (opts.macformat == true) fwrite (SUB_HEADER, 8, 1, fheader); fwrite(buffer, 2048, 1, fheader); last_pos = ftell(fsource); } while (opts.last_vd == false); // add padding data to header file for(i = 0; i < (long)sizeof(buffer); i++) // clear buffer buffer[i] = 0; remaining_length = 300 - (last_pos/sector_size); for(i = 0; i < remaining_length; i++) { if (opts.macformat == true) fwrite (SUB_HEADER, 8, 1, fheader); fwrite(buffer, 2048, 1, fheader); } fclose(fheader); if (opts.extractheaderonly == true) exit(0); // header saved, exit // add padding data to iso image if (last_pos > start_lba*sector_size) { printf("Sorry, LBA value is too small...\nIt should be at least %d for current ISO image (probably greater)", last_pos/sector_size); exit(1); } if (start_lba < 11700) printf("Warning! LBA value should be greater or equal to 11700 for multisession images\n"); printf("Adding padding data up to start LBA value..."); remaining_length = start_lba - (last_pos/sector_size); printf(" "); for(i = 0; i < remaining_length; i++) { if (!(i%512)) { progress = i*100/remaining_length; printf("\b\b\b%02d%%", progress); } if (opts.macformat == true) fwrite (SUB_HEADER, 8, 1, fdest); if (!fwrite(buffer, 2048, 1, fdest)) { printf("\nCan't write file! (disk full?)"); exit(1); } } printf("\b\b\b \b\b\b"); printf("Done!\n"); // append original iso image printf("Appending ISO image..."); fseek(fsource, 0L, SEEK_SET); remaining_length = image_length/sector_size; printf(" "); for(i = 0; i < remaining_length; i++) { if (!(i%512)) { progress = i*100/remaining_length; printf("\b\b\b%02d%%", progress); } if (!sector_read(buffer, sector_size, mode, fsource)) { printf("\nCan't read image!"); exit(1); } if (opts.macformat == true) fwrite (SUB_HEADER, 8, 1, fdest); if (!fwrite(buffer, 2048, 1, fdest)) { printf("\nCan't write file! (disk full?)"); exit(1); } } printf("\b\b\b \b\b\b"); printf("Done!\n"); printf("\nImage is now fixed!\n"); fclose(fsource); fclose(fdest); return 0; }
static int mbox_read(struct sbd_context *st, int mbox, struct sector_mbox_s *s_mbox) { return sector_read(st, MBOX_TO_SECTOR(mbox), s_mbox); }
static int slot_read(struct sbd_context *st, int slot, struct sector_node_s *s_node) { return sector_read(st, SLOT_TO_SECTOR(slot), s_node); }
/*-----------------------------------------------------------*/ UINT8_T sector_Open(UINT8_T index, UINT8_T aligment ,UINT32_T addr) { UINT16_T size; UINT8_T err=ERR_OK; SectorList *header=NULL; UINT8_T i; //подготовить if(aligment==0) return ERR_WRONG_ALIGMENT; size=(sizeof(SectorList)+(aligment-1)) & ~(aligment-1); header=(SectorList*)local_malloc( size ); if(header==NULL) return ERR_LOCAL_MALLOC; //чтение заголовка. Учитываем выравнивание size=(sizeof(SectorList)-sizeof(SectorInfo*)+(aligment-1)) & ~(aligment-1); err=sector_read(index, addr, (void*)header, size); if(err==ERR_OK) { i=~header->sector_counter; if(i == header->crc) { //создание структур err=sector_Create(header->sector_counter,aligment); if(err==ERR_OK) { err=sector_read(index, (addr+size), (void*)sl->sector, (sizeof(SectorInfo)*sl->sector_counter + (aligment-1)) & ~(aligment-1) ); if(err!=ERR_OK) { sector_ResourceFree(); } else { sl->crc=header->crc; //проверка CRC16 Crc16_Clear(); Crc16((UINT8_T*)&sl->sector_counter,sizeof(UINT8_T)); Crc16((UINT8_T*)&sl->crc,sizeof(UINT8_T)); sl->crc16=Crc16((UINT8_T*)sl->sector,sizeof(SectorInfo)*sl->sector_counter); if(header->crc16!=sl->crc16) { sector_ResourceFree(); err=ERR_CRC; } else { for(i=0;i<sl->sector_counter;i++) { if(sl->sector[i].Type!=SECTOR_FREE) { size=(sl->sector[index].pxEnd_Addr+sl->sector[index].bl_size)-sl->sector[index].StartAddr; ApplicationSectorOpenHook(i, sl->sector[i].StartAddr,size); } } } } } } else { err=ERR_CRC; } } local_free(header); return err; }