Ejemplo n.º 1
0
uint32_t atadisk_read(device_t *dev, uint64_t off, uint32_t size, char *buff) {
    info_t *info = (info_t *) dev->drvreg;
    ata_drive_t *drive = info->drive;
    uint32_t max_seccount = drive->mode == ATA_AMODE_LBA48 ? 0x10000 : 0x100;

    /* head */
    if (off % 512) {
        /* offset is not sector aligned */
        uint32_t rem = (off+512)/512 - off;
        if (size <= rem) {
            if (read_sector_part(info, off/512, off%512, size, buff))
                return EIO;
            buff += size;
            size = 0;
        } else {
            if (read_sector_part(info, off/512, off%512, rem, buff))
                return EIO;
            buff += rem;
            size -= rem;
        }
    }

    /* body */
    while (size >= 512) {
        /* read all remaining sectors */
        uint32_t sects = size/512;
        if (sects >= max_seccount) {
            if (read_sectors(info, max_seccount, off/512, buff))
                return EIO;
            size -= max_seccount*512;
            buff += max_seccount*512;
        } else {
            if (read_sectors(info, sects, off/512, buff))
                return EIO;
            size -= sects*512;
            buff += sects*512;
        }
    }

    /* tail*/
    if (size) {
        if (read_sector_part(info, off/512, 0, size, buff))
            return EIO;
    }

    /* done */
    return ESUCCESS;
}
Ejemplo n.º 2
0
unsigned ATA_DEVICE::read_data()
{
   if (!loaded())
       return 0xFFFFFFFF;
   if ((reg.devhead ^ device_id) & 0x10)
       return 0xFFFFFFFF;
   if (/* (reg.status & (STATUS_DRQ | STATUS_BSY)) != STATUS_DRQ ||*/ transptr >= transcount)
       return 0xFFFFFFFF;

   // DRQ=1, BSY=0, data present
   unsigned result = *(unsigned*)(transbf + transptr*2);
   transptr++;
//   printf(__FUNCTION__" data=0x%04X\n", result & 0xFFFF);

   if (transptr < transcount)
       return result;
   // look to state, prepare next block
   if (state == S_READ_ID || state == S_READ_ATAPI)
       command_ok();
   if (state == S_READ_SECTORS)
   {
//       __debugbreak();
//       printf("dev=%d, cnt=%d\n", device_id, reg.count);
       if(!--reg.count)
           command_ok();
       else
       {
           next_sector();
           read_sectors();
       }
   }

   return result;
}
Ejemplo n.º 3
0
/* some functions */
int gen_fat_info(struct fat_info *fti, struct mbr_entry mbe) {
	int ret = 0;
	struct fat_bpb bpb;
	
	if ((ret = read_sectors(mbe.start_sector, 1, (uint8_t *)&bpb)) == 0) { // read the bpb 
		if (is_supported_version(mbe.type_code)) {
			fti->type					= mbe.type_code;
			fti->bytes_per_sector		= bpb.bytes_per_sector;
			fti->sectors_per_cluster	= bpb.sectors_per_cluster;
			fti->first_sector			= mbe.start_sector;
			fti->first_fat_sector		= fti->first_sector + bpb.reserved_sector_cnt;
			fti->sectors_per_fat		= is_fat_32(mbe.type_code) ? bpb.fat32.sectors_per_fat : bpb.sectors_per_fat16;
			fti->first_cluster			= fti->first_fat_sector + (bpb.table_cnt * fti->sectors_per_fat);
			if (is_fat_32(mbe.type_code)) { /* too long to inline */
				fti->root_dir_sector	= clust_to_sect(fti->first_cluster, bpb.fat32.root_cluster, fti->sectors_per_cluster);
			} else {
				fti->root_dir_sector	= fti->first_fat_sector + (bpb.table_cnt * fti->sectors_per_fat);
			}
		} else {
			ret = mbe.type_code;
			printf("unsupported fat 0x%x\n", ret);
		}
	} else {
		printf("gen_fs_info() - unable to read in bpb, failed with %i\n", ret);
	}
	
	return ret;
}
Ejemplo n.º 4
0
void cdrom_driver::prefetch_sector(const unsigned int sec)
{
	int numpfsec=num_pf*num_pf_sectors,
			pfsec=sec-pf_head_sector;

//  printf("prefetch_sector: %d\n", sec);

	if ((pfsec<0) || (pfsec>numpfsec))
	{
		// Sector is not in prefetch buffer, abort current prefetch

		if (pf_status)
		{
			pf_status->cancel();
			pf_status->release();
		}

		// Reset the buffer and begin a new prefetch

		pf_head=0;
		pf_tail=0;
		num_pf=1;
		pf_head_sector=sec;

		last_pf_status=NULL;
		pf_status=read_sectors(sec, num_pf_sectors, pf_buffer);
	}
}
Ejemplo n.º 5
0
static void wbfs_load_header(void)
{
        head = wbfs_malloc(sizeof(*head));
        read_sectors(0,1,head);
        if(wbfs_ntohl(head->magic)!=MAGIC)
                wbfs_fatal("not a WBFS partition!");

        D(  wblk_sz_shift,     head->blk_sz_log2-2+15		);
        D(  iwlba_shift,     head->blk_sz_log2-9+15		);
        D(  lba_mask,	     ((1<<(wblk_sz_shift-blk_sz_shift))-1));
        D(  nsblk ,	     wbfs_ntohl(head->nsblk)			);
        D(  nblk ,	     nsblk*512LL/(blk_sz*0x8000)	);
        D(  freeblks_size,   ALIGN512(nblk/8)			);
        D(  disc_nblk,	     (143432/(1<<head->blk_sz_log2))+1	);
        D(  table_size,	     (disc_nblk)*2			);
        D(  header_size,     ALIGN512(table_size+0x100)		);
        D(  freeblks_o,      blk_sz*0x8000-freeblks_size	); // end of first block
        D(  max_disc,	     (freeblks_o-512)/header_size	);

        if(max_disc > MAX_MAXDISC)
                max_disc = MAX_MAXDISC;

        header = wbfs_malloc(header_size);
        tmp_buffer = wbfs_malloc(blk_sz);
}
Ejemplo n.º 6
0
/**
 * dev_read - read from a drive
 * @drive:	Drive number
 * @buf:	Pre-allocated buffer for output
 * @lba:	Position to start reading from
 * @sectors:	Number of sectors to read
 *
 * High-level routine to read from a hard drive.
 * Return the number of sectors read on success or -1 on failure.
 * errno_disk contains the error number.
 **/
int dev_read(int drive, void *buf, unsigned int lba, int sectors)
{
    struct driveinfo drive_info;
    drive_info.disk = drive;

    return read_sectors(&drive_info, buf, lba, sectors);
}
Ejemplo n.º 7
0
/* read from the virtual tivo disk (ie. all partitions
   concatenated) */
void mfs_read_sectors(void *buf, u32 sec, u32 count)
{
    int i;
    u64 start=0;

    if (vserver != -1) {
        vserver_read_sectors(buf, sec, count);
        return;
    }

    sec = partition_remap(sec);

    for (i=0; devs[i].dev; i++) {
        if (sec < start + devs[i].sectors) break;
        start += devs[i].sectors;
    }
    if (!devs[i].dev) {
        fprintf(stderr,"Failed to map sector %d\n", sec);
        exit(1);
    }

    if (verbose) {
        fprintf(stderr, "mapped %d to %s/%d\n", sec, devs[i].dev, (int)(sec-start));
    }

    read_sectors(devs[i].fd, buf, sec-start, count);

    if (need_bswap) {
        u16 *v = (u16 *)buf;
        for (i=0; i<count<<(SECTOR_SHIFT-1); i++) v[i] = ntohs(v[i]);
    }
}
Ejemplo n.º 8
0
/* 
 * Every sector of of the FAT holds 128 of these 32 bit integers, so looking up the next 
 * cluster of a file is relatively easy. Bits 7-31 of the current cluster tell you which sectors to read from the FAT, and bits 
 * 0-6 tell you which of the 128 integers in that sector contain is the number of the next cluster of your file (or if all ones, that the current cluster is the last).
 */
int main() {
	uint8_t *buf = NULL;
	int ret = 0;

	if ((fp = fopen("/dev/sdb", "rb")) != NULL) {
		if ((buf = malloc(MBR_SECTOR_SIZE)) != NULL) {
			struct mbr_entry *mbr = NULL;
			struct fat_info fti;
			
			/* read the mbr */
			if ((ret = read_sectors(0, 1, buf)) == 0) {
				mbr = (struct mbr_entry *)(buf + MBR_OFFSET);
				
				if ((ret = gen_fat_info(&fti, *mbr)) == 0) {
					if ((ret = read_directory(fti)) != 0) {
						printf("read_directory() failed with %i\n", ret);
					}
				} else {
					printf("gen_fat_info() failed with %i\n", ret);
				}
			} else {
				printf("read_sectors() failed with %i\n", ret);
			}
		} else {
			printf("Unable to allocate %i bytes!\n", MBR_SECTOR_SIZE);
		}
	} else {
		printf("Unable to open file!\n");
	}

	fclose(fp);
	free(buf);
	return 0;
}
Ejemplo n.º 9
0
int main (int argc, char **argv)
{
    /* This is a sample program.  If you want to print out sector 57 of
     * the disk, then run the program as:
     *
     *    ./readwrite disk 57
     *
     * You'll of course want to replace this with your own functions.
     */

    unsigned char buf[sector_size_bytes];        /* temporary buffer */
    int           the_sector;                     /* IN: sector to read */

    if ((device = open(argv[1], O_RDWR)) == -1) {
        perror("Could not open device file");
        exit(-1);
    }

    the_sector = atoi(argv[2]);
    //printf("Dumping sector %d:\n", the_sector);
    read_sectors(the_sector, 1, buf);
    //print_sector(buf);
	parse_MBR(buf);

    close(device);
    return 0;
}
Ejemplo n.º 10
0
/*
 * The following calls use a bastardized fp on Windows that contains:
 * fp->_ptr: a Windows handle
 * fp->_bufsiz: the sector size
 * fp->_cnt: a file offset
 */
int contains_data(FILE *fp, uint64_t Position,
                  const void *pData, uint64_t Len)
{
   unsigned char aucBuf[MAX_DATA_LEN];
   HANDLE hDrive = (HANDLE)fp->_ptr;
   uint64_t SectorSize = (uint64_t)fp->_bufsiz;
   uint64_t StartSector, EndSector, NumSectors;
   Position += (uint64_t)fp->_cnt;

   StartSector = Position/SectorSize;
   EndSector   = (Position+Len+SectorSize-1)/SectorSize;
   NumSectors  = (size_t)(EndSector - StartSector);

   if((NumSectors*SectorSize) > MAX_DATA_LEN)
   {
      uprintf("contains_data: please increase MAX_DATA_LEN in file.h\n");
      return 0;
   }

   if(Len > 0xFFFFFFFFUL)
   {
      uprintf("contains_data: Len is too big\n");
      return 0;
   }

   if(read_sectors(hDrive, SectorSize, StartSector,
                     NumSectors, aucBuf) <= 0)
      return 0;

   if(memcmp(pData, &aucBuf[Position - StartSector*SectorSize], (size_t)Len))
      return 0;
   return 1;
} /* contains_data */
Ejemplo n.º 11
0
/**
 * read_mbr - return a pointer to a malloced buffer containing the mbr
 * @drive:	Drive number
 * @buf:	Pre-allocated buffer for output
 *
 * Return the number of sectors read on success or -1 on failure.
 * errno_disk contains the error number.
 **/
int read_mbr(int drive, void *buf)
{
    struct driveinfo drive_info;
    drive_info.disk = drive;

    /* MBR: lba = 0, 1 sector */
    return read_sectors(&drive_info, buf, 0, 1);
}
Ejemplo n.º 12
0
void wbfs_open_disc(u8*discid)
{
        u32 i;
        for(i=0;i<max_disc;i++)
        {
                if (head->disc_table[i]){
                        read_sectors(1+i*header_size/512,1,tmp_buffer);
                        u32 magic=wbfs_be32(tmp_buffer+24);
                        if(magic!=0x5D1C9EA3)
                                continue;
                        if(wbfs_memcmp(discid,tmp_buffer,6)==0){
                                read_sectors(1+i*header_size/512,header_size/512,header);
                                return;
                        }
                }
        }
        
}
Ejemplo n.º 13
0
/*
 * parse MBR, skip first 446 bytes
 *
 * */
void parse_MBR(unsigned char *buf)
{
		
    int i,j;
	int length = 16;
	//int partition = 0;
    int base = 446;	
	unsigned char extend[sector_size_bytes];
	struct partition * pt;
	struct partition * ext;
	struct partition * ext_pt;
	unsigned int ext_start_sect;
	unsigned int logi_start_sect;
	for(i = 0; i < 4; i++)
	{
		pt = (struct partition*) (buf + base + length*i);
		printf("0x%02X %d %d\n", pt->sys_ind, pt->start_sect, pt->nr_sects);
	}
	ext_start_sect = pt->start_sect;


	for(j=0; j<2; j++)
	{
		read_sectors(ext_start_sect, 1, extend);
		ext = (struct partition*) (&extend[base]);
		ext_pt = (struct partition*) (&extend[base+length]);
		logi_start_sect = ext_start_sect + ext->start_sect;

		ext_start_sect = pt->start_sect + ext_pt->start_sect;
		printf("0x%02X %d %d\n", ext->sys_ind, logi_start_sect, ext->nr_sects);
	}

    //for (i = 446; i < sector_size_bytes; i++) {
        //printf("%02x", buf[i]);
	//	parts[partition/16][partition%16] = buf[i];
		/*
        if (partition % 16 == 0)
		{
			printf("\n");      
			partition = 0;
		}*/
		/*
		if ((ct)%4 == 1)
			printf("partition type: %02x", buf[i]);
			*/
        /*if (!((i+1) % 4))
            printf(" "); */
	//	partition += 1;
    //}
	

	//for(i = 0; i < 4; i++)
	//{
	//	parse_partition(parts[i]);
	//	printf ("\n");
	//}
}
Ejemplo n.º 14
0
/* Do some initialize stuff */
void init(char * deviceName) {
    /* open FAT32 filesystem */
    if( (fd = open(deviceName,O_RDWR)) == -1 )
        report_exit("Open device error!");

    /* read the DOS Boot Record(DBR)=512 Bytes */
    int count;
    if( (count=read(fd,buffer,512)) != 512 )
        report_exit("read Boot Sector error!");

    /* check file system signature (0xAA55) */
    if( buffer[510] != 0x55 && buffer[511] != 0xAA )
        report_exit("Not a valid filesystem!");

    /* copy the Boot Sector */
    memcpy(&be,buffer,sizeof(struct BootEntry));
    bps = be.BPB_BytsPerSec;
    spc = be.BPB_SecPerClus;
    dps=spc*bps/sizeof(DirEntry);

    /* copy the FSINFO */
    read_sectors(be.BPB_FSInfo,buffer,1);
    memcpy(&fsinfo,buffer,sizeof(struct FSInfo));

    /* calculate the FAT starting address */
    fat_secNum = fat_addr = be.BPB_RsvdSecCnt;

    /* calculate the starting sector of data area, locates just after FAT */
    data_secNum = fat_secNum +  be.BPB_NumFATs * be.BPB_FATSz32;

    /* calculate the cluster and sector of root directory */
    rootDir_clusterNum = be.BPB_RootClus;
    rootDir_secNum = data_secNum + (be.BPB_RootClus-2) * spc;

    /* allocate a temporary FAT for reading and writing */
    FAT = (ULONG*)malloc(be.BPB_FATSz32 * bps);

    /* read contents in FAT to temporary FAT buffer */
    read_sectors(fat_addr,(unsigned char *)FAT, be.BPB_FATSz32);
}
Ejemplo n.º 15
0
int32_t read_sector_part(info_t *info,
                         uint64_t lba,
                         uint32_t off,
                         uint32_t size,
                         char *buf) {
    int32_t err, i;
    while(info->cache_lock);
    info->cache_lock = 1;
    if (info->cache_sect != lba) {
        if (err = read_sectors(info, 1, lba, info->cache_data))
            return err;
    }
    for (i = off; i < off+size; i++)
        *buf++ = info->cache_data[i];
    info->cache_lock = 0;
    return 0;
}
Ejemplo n.º 16
0
/**
 * write_verify_sectors - write several sectors from disk
 * @drive_info:		driveinfo struct describing the disk
 * @lba:		Position to write
 * @data:		Buffer to write
 * @size:		Size of the buffer (number of sectors)
 **/
int write_verify_sectors(struct driveinfo *drive_info,
			 const unsigned int lba,
			 const void *data, const int size)
{
    char *rb = malloc(SECTOR * size);
    int status;

    if (write_sectors(drive_info, lba, data, size) == -1)
	return -1;		/* Write failure */

    if (read_sectors(drive_info, rb, lba, size) == -1)
	return -1;		/* Readback failure */

    status = memcmp(data, rb, SECTOR * size);
    free(rb);
    return status ? -1 : 0;
}
Ejemplo n.º 17
0
Archivo: main.c Proyecto: fchai/cnix
int load_kernel (void)
    {
    int lba = ((int) __boot_end) / 512;
    uint8_t * buff = __boot_loader_end;

    do {
        if (0 != read_sectors (lba, buff, 1))
            {
            printf ("read fail\n");
            return;
            }
        lba++;
        buff += 512;
        } while (((unsigned int *) buff) [-1] != CNIX_END_FLAG);

    return buff - __boot_loader_end;
    }
Ejemplo n.º 18
0
static void handle_bio(struct bio *bio)
{
	if (bio->map.length % IDE_SECTOR_SIZE) {
		finish_bio(bio, BIO_FAILED);
		return;
	}

	char *page = page_addr(bio->map.page);
	const unsigned long long lba = bio->map.sector;
	const size_t count = bio->map.length / IDE_SECTOR_SIZE;
	void *data = page + bio->map.offset;
	const int rc = bio->dir == BIO_READ
				? read_sectors(data, lba, count)
				: write_sectors(data, lba, count);

	finish_bio(bio, rc == 0 ? BIO_FINISHED : BIO_FAILED);
}
Ejemplo n.º 19
0
/*
 * Perform a read of a sequence of blocks; return the number of blocks
 *    successfully sequentially read.
 */
static int64_t do_read (HANDLE hDrive, unsigned char * buffer, uint64_t tryout, uint64_t block_size,
		    blk_t current_block)
{
	int64_t got;

	if (v_flag > 1)
		print_status();

	/* Try the read */
	got = read_sectors(hDrive, block_size, current_block, tryout, buffer);
	if (got < 0)
		got = 0;
	if (got & 511)
		uprintf("%sWeird value (%ld) in do_read\n", bb_prefix, got);
	got /= block_size;
	return got;
}
Ejemplo n.º 20
0
/*
 * traverse all cluster belonged to the DirEntry de,
 * pass the cluster read to func for processing
 * set a value `value_addr' to indicate the stop address
 */
int _traverse(DirEntry * de,int (*func)(unsigned char *,int,ULONG *),
              ULONG * value_addr) {
    int result=0;
    ULONG base_sector,dir_cluster;
    ULONG nRemain = de->DIR_FileSize;
    dir_cluster = getDirClusterNum(de);

    if( nRemain == 0 ) {
        /* for a Directory DirEntry.size= 0
         * set to INF to keep the traverse going*/
        if( de->DIR_Attr & ATTR_DIR ) nRemain = INF;
        /* some normal file may have size=0,no allocated cluster for it */
        else return 1;
    }

    /* traverse the FAT chain */
    ULONG stopat,len=0;
    do {
        base_sector = data_secNum + spc*(dir_cluster-2);
        /* read the whole cluster */
        len = read_sectors(base_sector,buffer,spc);
#ifdef DEBUG
        printf("Cluster : %lu\n",dir_cluster);
        printf("Sector : %lu\n",base_sector);
        printf("Read:   %lu\nRemain: %lu\n",len,nRemain);
#endif
        /* pass the buffer content to func for processing
         * NOTE: result=1 means keep traversing
         * result=0 means stop traversing, and stopat point to
         * the stop position in buffer
         * */
        if(nRemain<len) result = func(buffer,nRemain,&stopat);
        else result = func(buffer,len,&stopat);
        if( result == 0 ) {
            *value_addr = (cluster2sector(dir_cluster)*bps + stopat);
            break;
        }

        nRemain -= len;
        dir_cluster=FAT[dir_cluster];
    } while( dir_cluster < END_MARK );
    return result;
}
Ejemplo n.º 21
0
int main (void) {
  int cmd_key, loop, reset;
  scp = (sata_core *)(SATA_CORE_BASE);
  scp->ctrl_reg = REG_CLEAR;
  scp->cmd_reg = REG_CLEAR;
 
  xil_printf("\n\r STATUS REG : %x\r\n", scp->status_reg);
  // SATA CORE RESET
  while ((scp->status_reg & SATA_LINK_READY) != SATA_LINK_READY) {
    scp->ctrl_reg = SW_RESET;
    xil_printf("\n\r ---GTX RESET--- \r\n");
    scp->ctrl_reg = REG_CLEAR;
    for(i=0; i<10000000; i++);
      j = j+i;
    xil_printf("\n\r STATUS REG : %x\r\n", scp->status_reg);
  }
  // SATA CORE RESET 
 
  xil_printf("\n\r ---Testing Sata Core--- \r\n");
 
  while (loop != 51) {
  
  // Read/Write Command 
    xil_printf("\n\rSelect Command: Read-(1) or Write-(2): \r\n");
    cmd_key = uartstat[0];
    while(cmd_key < '0' || cmd_key > '9') cmd_key = uartstat[0]; 		
    printf("\nKey:%d", cmd_key); 
    if(cmd_key == 49) 
      read_sectors(SECTOR_ADDRESS, NUM_SECTORS);
    else {
      write_sectors(SECTOR_ADDRESS, NUM_SECTORS);
    }
 
    xil_printf("\n\n\rExit(e)?: Press '3'\r\n");
    loop = uartstat[0];
    while(loop < '0' || loop > '9') loop = uartstat[0]; 		
    //scp->ctrl_reg = REG_CLEAR;
  }

  xil_printf("\n\n\r Done ! \r\n");
  
  return 0;
}
Ejemplo n.º 22
0
u32 wbfs_get_list( u8 **headers,u32 num)
{
        u32 i;
        u32 count = 0;
        for(i=0;i<max_disc;i++)
        {
                if (head->disc_table[i])
                {
                        read_sectors(1+i*header_size/512,header_size/512,header);
                        u32 magic=wbfs_be32(header+24);
                        if(magic!=0x5D1C9EA3)
                                continue;
                        headers[i] = wbfs_malloc(header_size);
                        wbfs_memcpy(headers[i],header,header_size);
                        if(++count == num)
                                return count;
                }
        }
        return count;
}
Ejemplo n.º 23
0
/* May read/write the same sector many times, but compatible with existing ms-sys */
int write_data(FILE *fp, uint64_t Position,
               const void *pData, uint64_t Len)
{
   unsigned char aucBuf[MAX_DATA_LEN];
   HANDLE hDrive = (HANDLE)fp->_ptr;
   uint64_t SectorSize = (uint64_t)fp->_bufsiz;
   uint64_t StartSector, EndSector, NumSectors;
   Position += (uint64_t)fp->_cnt;

   StartSector = Position/SectorSize;
   EndSector   = (Position+Len+SectorSize-1)/SectorSize;
   NumSectors  = EndSector - StartSector;

   if((NumSectors*SectorSize) > MAX_DATA_LEN)
   {
      uprintf("Please increase MAX_DATA_LEN in file.h\n");
      return 0;
   }

   if(Len > 0xFFFFFFFFUL)
   {
      uprintf("write_data: Len is too big\n");
      return 0;
   }

   /* Data to write may not be aligned on a sector boundary => read into a sector buffer first */
   if(read_sectors(hDrive, SectorSize, StartSector,
                     NumSectors, aucBuf) <= 0)
      return 0;

   if(!memcpy(&aucBuf[Position - StartSector*SectorSize], pData, (size_t)Len))
      return 0;

   if(write_sectors(hDrive, SectorSize, StartSector,
                     NumSectors, aucBuf) <= 0)
      return 0;
   return 1;
} /* write_data */
Ejemplo n.º 24
0
static int
read_tracks(teledisk_prop_t *prop)
{
  int a, t1, t2, t3, t4;

  t1 = fgetc(prop->f);
  t2 = fgetc(prop->f);
  t3 = fgetc(prop->f);
  t4 = fgetc(prop->f);

  //printf("TRACK: %02x %02x %02x %02x\n", t1, t2, t3, t4);

  if (t1 == 0xff) // end marker?
    {
      //printf("TRACK END MARKER?\n");
      return 1;
    }

  for (a = 0;a < t1;a++)
    if (read_sectors(prop) < 0)
      return -1;

  return 0;
}
Ejemplo n.º 25
0
int direct_dump(struct task *task, char *dump_path, int force_mode)
{
	char *data, *bitmap;
	char *colon, *off_str;
	struct leader_record *lr;
	struct request_record *rr;
	struct sync_disk sd;
	char sname[NAME_ID_SIZE+1];
	char rname[NAME_ID_SIZE+1];
	uint64_t sector_nr;
	int sector_count, datalen, align_size;
	int i, rv, b;

	memset(&sd, 0, sizeof(struct sync_disk));

	colon = strstr(dump_path, ":");
	if (colon) {
		off_str = colon + 1;
		*colon = '\0';
		sd.offset = atoll(off_str);
	}

	strncpy(sd.path, dump_path, SANLK_PATH_LEN);
	sd.fd = -1;

	rv = open_disk(&sd);
	if (rv < 0)
		return -ENODEV;

	rv = direct_align(&sd);
	if (rv < 0)
		goto out_close;

	align_size = rv;
	datalen = align_size;
	sector_count = align_size / sd.sector_size;

	data = malloc(datalen);
	if (!data) {
		rv = -ENOMEM;
		goto out_close;
	}

	printf("%8s %36s %48s %10s %4s %4s %s",
	       "offset",
	       "lockspace",
	       "resource",
	       "timestamp",
	       "own",
	       "gen",
	       "lver");

	if (force_mode)
		printf("/req/mode");

	printf("\n");

	sector_nr = 0;

	while (1) {
		memset(sname, 0, sizeof(rname));
		memset(rname, 0, sizeof(rname));
		memset(data, 0, sd.sector_size);

		rv = read_sectors(&sd, sector_nr, sector_count, data, datalen,
				  task, "dump");

		lr = (struct leader_record *)data;

		if (lr->magic == DELTA_DISK_MAGIC) {
			for (i = 0; i < sector_count; i++) {
				lr = (struct leader_record *)(data + (i * sd.sector_size));

				if (!lr->magic)
					continue;

				/* has never been acquired, don't print */
				if (!lr->owner_id && !lr->owner_generation)
					continue;

				strncpy(sname, lr->space_name, NAME_ID_SIZE);
				strncpy(rname, lr->resource_name, NAME_ID_SIZE);

				printf("%08llu %36s %48s %010llu %04llu %04llu",
					(unsigned long long)((sector_nr + i) * sd.sector_size),
					sname, rname,
					(unsigned long long)lr->timestamp,
					(unsigned long long)lr->owner_id,
					(unsigned long long)lr->owner_generation);

				if (force_mode) {
					bitmap = (char *)lr + LEADER_RECORD_MAX;
					for (b = 0; b < DEFAULT_MAX_HOSTS; b++) {
						if (test_id_bit(b+1, bitmap))
							printf(" %d", b+1);
					}
				}
				printf("\n");
			}
		} else if (lr->magic == PAXOS_DISK_MAGIC) {
			strncpy(sname, lr->space_name, NAME_ID_SIZE);
			strncpy(rname, lr->resource_name, NAME_ID_SIZE);

			printf("%08llu %36s %48s %010llu %04llu %04llu %llu",
			       (unsigned long long)(sector_nr * sd.sector_size),
			       sname, rname,
			       (unsigned long long)lr->timestamp,
			       (unsigned long long)lr->owner_id,
			       (unsigned long long)lr->owner_generation,
			       (unsigned long long)lr->lver);

			if (force_mode) {
				rr = (struct request_record *)(data + sd.sector_size);
				printf("/%llu/%u",
				       (unsigned long long)rr->lver, rr->force_mode);
			}
			printf("\n");

			for (i = 0; i < lr->num_hosts; i++) {
				char *pd = data + ((2 + i) * sd.sector_size);
				struct mode_block *mb = (struct mode_block *)(pd + MBLOCK_OFFSET);

				if (!(mb->flags & MBLOCK_SHARED))
					continue;

				printf("                                                                                                          ");
				printf("%04u %04llu SH\n", i+1, (unsigned long long)mb->generation);
			}
		} else {
			break;
		}

		sector_nr += sector_count;
	}

	rv = 0;
	free(data);
 out_close:
	close_disks(&sd, 1);
	return rv;
}
Ejemplo n.º 26
0
int read_directory(struct fat_info fti) {
	int ret = 0;
	uint8_t *buf = NULL;
	struct dir_entry *de = NULL;
	printf("entries per cluster: %lu\n", (fti.bytes_per_sector * fti.sectors_per_cluster) / sizeof(struct dir_entry));
	if (fti.bytes_per_sector > 0) { /* sanity check */
		if ((buf = malloc(fti.bytes_per_sector * fti.sectors_per_cluster)) != NULL) {
			if ((ret = read_sectors(fti.root_dir_sector, fti.sectors_per_cluster, buf)) == 0) {
				de = (struct dir_entry *)buf;
				int cnt = 0;
				
				while (de->short_fname[0] != 0) {
					printf("dir_entry[%i]\n", cnt);
					
					if (de->short_fname[0] != 0xE5) { /* delete or LFN */
						if (de->attr == ATTR_VOLUME_ID) {
							printf("VOLUME ID\n");
							printf("volume: %s\n", de->short_fname);
						} else if ((de->attr & ATTR_ARCHIVE) == ATTR_ARCHIVE) {
							size_t size = 0;
							char *fname = NULL;
							
							if (lfn_strlen(de, &size) == 0) {
								printf("strlen: %lu\n", size);
								if ((fname = malloc(size + 1)) != NULL) {
									if (lfn_read_fname(de, fname) == 0) {
										printf("file name: %s\n", fname);
									} else {
										printf("lfn_read_fname() failed!\n");
									}
								} else {
									printf("unable to allocate %lu bytes!\n", size);
									break;
								}
								
								free(fname);
							} else {
								printf("lfn_strlen() failed!\n");
								break;
							}
							
							printf("FILE ENTRY\n");
							printf("name: [%s]\n", de->short_fname);
							printf("attr: 0x%x\n", de->attr);
							printf("cluster_high: %i\n", de->cluster_high);
							printf("cluster_low: %i\n", de->cluster_low);
							printf("size: %i\n", de->size);

						} else if (de->attr == ATTR_LFN) {
							printf("LFN ENTRY\n");
							struct lfn_entry *lfn = (struct lfn_entry *)de;
							printf("seq_num: 0x%x\n", lfn->seq_num);
						}
					} else {
						printf("UNUSED/DELTED ENTRY\n");
					}
					
					printf("\n");
					de++;
					cnt++;
				}
						
				
			} else {
				printf("read_directory() - read_sectors returned %i\n", ret);
			}
		} else {
			ret = -1;
			printf("read_directory() - unable to allocate %i bytes!\n", fti.bytes_per_sector);
		}
	} else {
		ret = -2;
		printf("read_directory() - fti.bytes_per_sector is zero.\n");
	}
		
	free(buf);
	return 0;
}
Ejemplo n.º 27
0
bool cdrom_driver::is_prefetch_sector_loaded(const unsigned int sec)
{
	int numpfsec=num_pf*num_pf_sectors,
			pfsec=sec-pf_head_sector;

	if ((pfsec<0) || (pfsec>=numpfsec))
	{
		// Requested sector is not in prefetch buffer, begin a new prefetch

		prefetch_sector(sec);
		pfsec=sec-pf_head_sector;
		numpfsec=num_pf*num_pf_sectors;
	}

	int blk=pfsec/num_pf_sectors;

	if (blk>0)
	{
		// Discard blocks below the prefetch point

		pf_head=(pf_head+blk)%num_pf_buffers;
		pf_head_sector+=num_pf_sectors*blk;
		pfsec-=num_pf_sectors*blk;
		num_pf-=blk;
		blk=0;
	}

	bool comp=((! pf_status) || (pf_status->complete()));

	if (! comp)
	{
		INT64 curtime=m_machine->device<cpu_device>("maincpu")->total_cycles();

		if (last_pf_status!=pf_status)
		{
			last_pf_status=pf_status;
			pf_timeout_begin=curtime;
		}

		INT64 timeout=curtime-pf_timeout_begin;
		int timeout_sec=(int)(timeout/timestamp_frequency);
		if (timeout_sec>20)
		{
			printf("cdrom: prefetch timed out, trying again...\n");
			num_pf=0;
			pf_head_sector=-1;
			prefetch_sector(sec);
			return is_prefetch_sector_loaded(sec);
		}
	}

	if ((num_pf<num_pf_buffers) && (comp))
	{
		// The prefetch buffer is not full and we are not waiting on IO,
		// prefetch the next block

		pf_tail=(pf_tail+1)%num_pf_buffers;
		num_pf++;

		int nxtsec=pf_head_sector+((num_pf-1)*num_pf_sectors);
		unsigned char *ptr=pf_buffer+((pf_tail*num_pf_sectors)*native_sector_size);

		if (pf_status)
		{
			pf_status->release();
			pf_status=last_pf_status=NULL;
		}

		pf_status=read_sectors(nxtsec, num_pf_sectors, ptr);
	}

	if (blk==(num_pf-1))
	{
		// The sector we want is in the last block in the prefetch buffer
		// which might still be loading, check if the sector we want is loaded
#if 0 // we do not load async in MESS
		INT64 trans=pf_status->bytes_transferred();
		unsigned int secmod=pfsec%num_pf_sectors,
								 needbytes=(secmod+1)*native_sector_size;

		if (trans<needbytes)
		{
			// The sector is not loaded yet

			return false;
		} else
#endif
		{
			// The sector is loaded

			return true;
		}
	} else
	{
		// The sector is not in the last block so it must be loaded

		return true;
	}
}
void Fat16_Read(MassStorageType *ms, uint32 logical_address, uint32 transfer_length)
{       
    uint32 end_address = logical_address + transfer_length - 1;
    Sink sink_bulk_out = StreamUsbEndPointSink(end_point_bulk_out);
    
    MS_DEBUG(("FAT16: Read log addr: %ld end addr: %ld\n", logical_address, end_address));
    
    if (!ms->info_read)
    {
        /* information read once from read-only file system */
        uint32 fat_number_sectors;
        uint32 root_number_sectors;
        uint32 data_number_sectors;   
    
        /* FAT size calculations */
        fat_number_sectors = ms->file_info[FILE_INFO_FAT].size / BYTES_PER_SECTOR + 1;       
        if ((ms->file_info[FILE_INFO_FAT].size % BYTES_PER_SECTOR) == 0)
        {            
            fat_number_sectors--;
        }
        ms->file_info[FILE_INFO_FAT].end_sector = FAT1_SECTOR + fat_number_sectors - 1;
    
        /* Root dir size calculations */
        root_number_sectors = ms->file_info[FILE_INFO_ROOT_DIR].size / BYTES_PER_SECTOR + 1;        
        if ((ms->file_info[FILE_INFO_ROOT_DIR].size % BYTES_PER_SECTOR) == 0)
        {            
            root_number_sectors--;
        }
        ms->file_info[FILE_INFO_ROOT_DIR].end_sector = ROOT_SECTOR + root_number_sectors - 1;
    
        /* Data area size calculations */
        data_number_sectors = ms->file_info[FILE_INFO_DATA].size / BYTES_PER_SECTOR + 1;       
        if ((ms->file_info[FILE_INFO_DATA].size % BYTES_PER_SECTOR) == 0)
        {            
            data_number_sectors--;
        }
        ms->file_info[FILE_INFO_DATA].end_sector = DATA_SECTOR + data_number_sectors - 1;
    
        /* don't read this information again to speed things up */
        ms->info_read = TRUE;
    }
    
    while (logical_address <= end_address)
    {
        MS_DEBUG(("FAT16: log addr: %ld\n", logical_address));
        if (logical_address == MBR_SECTOR) /* Master Boot Record */
        {            
            uint8 *buffer = 0;
            
            /* wait for free space in Sink */
            Fat16_WaitAvailable(sink_bulk_out, BYTES_PER_SECTOR);
            
            if ((buffer = claimSink(sink_bulk_out, BYTES_PER_SECTOR)) != 0)
            {
                uint16 offset = 0;
                uint16 size_data = sizeof(MasterBootRecordExeType);
                memmove(buffer, &mbr_exe, size_data);
                offset += size_data;            
                size_data = sizeof(MasterBootRecordPartitionType);
                memmove(buffer + offset, &mbr_partition, size_data);
                offset += size_data;
                memset(buffer + offset, 0, size_data * 3);
                size_data = sizeof(ExeSignatureType);            
                memmove(buffer + BYTES_PER_SECTOR - size_data, &exe_signature, size_data);                
                SinkConfigure(sink_bulk_out, VM_SINK_USB_TRANSFER_LENGTH, BYTES_PER_SECTOR);
                SinkFlush(sink_bulk_out, BYTES_PER_SECTOR);
                MS_DEBUG(("FAT16: MBR returned data\n"));                
            }
            logical_address++;
        }
        else if (logical_address == BOOT_SECTOR) /* Boot Sector */
        {       
            uint8 *buffer = 0;  
            
            /* wait for free space in Sink */
            Fat16_WaitAvailable(sink_bulk_out, BYTES_PER_SECTOR);
                          
            if ((buffer = claimSink(sink_bulk_out, BYTES_PER_SECTOR)) != 0)
            {
                uint16 offset = 0;
                uint16 size_data = sizeof(BootSectorType);
                memmove(buffer, &boot_sector, size_data);
                offset += size_data;
                size_data = sizeof(BootSectorExeType);
                memmove(buffer + offset, &boot_exe, size_data);
                offset += size_data;
                size_data = sizeof(ExeSignatureType);
                memmove(buffer + offset, &exe_signature, size_data);
                SinkConfigure(sink_bulk_out, VM_SINK_USB_TRANSFER_LENGTH, BYTES_PER_SECTOR);
                SinkFlush(sink_bulk_out, BYTES_PER_SECTOR);
                MS_DEBUG(("FAT16: BOOT returned data\n"));
            }
            logical_address++;
        }
        else if ((logical_address >= FAT1_SECTOR) && (logical_address <= ms->file_info[FILE_INFO_FAT].end_sector)) /* FAT 1 */
        {
            MS_DEBUG(("FAT16: FAT1 sector\n"));
            logical_address = read_sectors(&ms->file_info[FILE_INFO_FAT], logical_address, end_address - logical_address + 1, FAT1_SECTOR);
        }
        else if ((logical_address >= FAT2_SECTOR) && (logical_address <= (ms->file_info[FILE_INFO_FAT].end_sector + SECTORS_PER_FAT))) /* FAT 2 */
        {
            MS_DEBUG(("FAT16: FAT2 sector\n"));
            logical_address = read_sectors(&ms->file_info[FILE_INFO_FAT], logical_address, end_address - logical_address + 1, FAT2_SECTOR);
        }
        else if ((logical_address >= ROOT_SECTOR) && (logical_address <= ms->file_info[FILE_INFO_ROOT_DIR].end_sector)) /* Root Directory */
        {
            MS_DEBUG(("FAT16: root sector\n"));
            logical_address = read_sectors(&ms->file_info[FILE_INFO_ROOT_DIR], logical_address, end_address - logical_address + 1, ROOT_SECTOR);
        }
        else if ((logical_address >= DATA_SECTOR) && (logical_address <= ms->file_info[FILE_INFO_DATA].end_sector)) /* Data Area */
        {
            MS_DEBUG(("FAT16: data sector\n"));
            logical_address = read_sectors(&ms->file_info[FILE_INFO_DATA], logical_address, end_address - logical_address + 1, DATA_SECTOR);
        }
        else /* sector with no data */
        {
            uint8 *buffer = 0;
            
            /* wait for free space in Sink */
            Fat16_WaitAvailable(sink_bulk_out, BYTES_PER_SECTOR);
                
            if ((buffer = claimSink(sink_bulk_out, BYTES_PER_SECTOR)) != 0)
            {
                memset(buffer, 0, BYTES_PER_SECTOR);                
                SinkConfigure(sink_bulk_out, VM_SINK_USB_TRANSFER_LENGTH, BYTES_PER_SECTOR);
                SinkFlush(sink_bulk_out, BYTES_PER_SECTOR);
                MS_DEBUG(("FAT16: empty sector\n"));
            }
            logical_address++;
        }
    }
}
Ejemplo n.º 29
0
int
create_extended_partition(int fd, int secno, int size) {
	int sec = secno;
	int cursec = secno;
	int pno = partno;	/* number of extd partition */
	int ei = eptsct-1;
	unsigned char type = 0x5;
	int lastseen = secno;
	int ok = 0;

	if (epts[ei].secno != secno) {
		fprintf(stderr, "%s: program bug\n", progname);
		exit(1);
	}

	outmsg("candidate ext pt", secno, secno+1, type);
	addpart(secno, 1, type);		/* size to be filled in later */
	
	while(1) {
		char buf[512];
		struct partition *p1, *p2, *pr, *pe;
		p1 = (struct partition *)(& epts[ei].pt4[0]);
		p2 = (struct partition *)(& epts[ei].pt4[16]);
		/* for the time being we just ignore the rest */

		if (is_extended(p1->sys_type)) {
			pr = p2;
			pe = p1;
		} else if (is_extended(p2->sys_type)) {
			pr = p1;
			pe = p2;
		} else if (p1->sys_type == 0) {
			pr = p2;
			pe = 0;
		} else if (p2->sys_type == 0) {
			pr = p1;
			pe = 0;
		} else
			break;

		/* first handle the real partition, if any */
		if (pr->sys_type != 0) {
			int ss = cursec + pr->start_sect;
			int es = ss + pr->nr_sects;
			outmsg("found in ept", ss, es, pr->sys_type);
			addpart(ss, pr->nr_sects, pr->sys_type);
			if (lastseen < es - 1)
				lastseen = es - 1;
			if (lastseen >= size)
				break;
		}


		/* then the extended link */

		if (!pe) {
			ok = 1;
			break;
		}
		type = pe->sys_type;
		cursec = sec + pe->start_sect;
		if (cursec >= size)
			break;
		read_sectors(fd, buf, cursec, 1);
		addepts(cursec, buf);
		ei = eptsct-1;
	}

	if (!ok || lastseen == secno) {
		printf("# retracted\n");
		partno = pno;
		return 0;
	}

	pts[pno].type = type;
	pts[pno].size = lastseen+1-secno;
	outmsg("extended part ok", secno, lastseen+1, type);
	return lastseen;
}
Ejemplo n.º 30
0
int
main(int argc, char **argv){
	int i,j,fd;
	long size;
	int pagesize, pagesecs;
	unsigned char *bp;
	struct ext2_super_block *e2bp;
	struct fat16_boot_sector *fat16bs;
	struct fat32_boot_sector *fat32bs;

	progname = argv[0];

	if (argc != 2) {
		fprintf(stderr, "call: %s device\n", progname);
		exit(1);
	}

	device = argv[1];

	fd = open(device, O_RDONLY);
	if (fd < 0) {
		perror(device);
		fprintf(stderr, "%s: could not open %s\n", progname, device);
		exit(1);
	}

	if (ioctl(fd, BLKGETSIZE, &size)) {
		struct stat s;
		perror("BLKGETSIZE");
		fprintf(stderr, "%s: could not get device size\n", progname);
		if (stat(device, &s)) {
			fprintf(stderr, "and also stat fails. Aborting.\n");
			exit(1);
		}
		size = s.st_size / 512;
	}

	pagesize = getpagesize();
	if (pagesize <= 0)
		pagesize = 4096;
	else if (pagesize > MAXPAGESZ) {
		fprintf(stderr, "%s: ridiculous pagesize %d\n", progname, pagesize);
		exit(1);
	}
	pagesecs = pagesize/512;

	printf("# partition table of %s\n", device);
	printf("# total size %ld sectors\n", size);
	printf("unit: sectors\n");

	for(i=0; i<size; i++) {
		if (i/BUFSECS != bufstart) {
			int len, secno;
			bufstart = i/BUFSECS;
			secno = bufstart*BUFSECS;
			len = BUFSECS;
			if (size - secno < len)
				len = size - secno;
			len = (len / 2)*2;	/* avoid reading the last (odd) sector */
			read_sectors(fd, buf, secno, len);
		}
			
		j = i % BUFSECS;

		bp = buf + 512 * j;

		if (bp[510] == 0x55 && bp[511] == 0xAA) {
			char *cp = bp+512-2-64;
			int j;

			if (i==0)
				continue; /* the MBR is supposed to be broken */

			/* Unfortunately one finds extended partition table sectors
			   that look just like a fat boot sector, except that the
			   partition table bytes have been overwritten */
			/* typical FAT32 end: "nd then press ...", followed by
			   IO.SYS and MSDOS.SYS and WINBOOT.SYS directory entries.
			   typical extd part tab end: 2 entries, 32 nul bytes */

			for(j=0; j<32; j++)
				if (cp[32+j])
					goto nonzero;
			addepts(i, bp);
			if (i > 0) {
				j = create_extended_partition(fd, i, size);
				if (j && j > i)
					i = j;	/* skip */
			}
			continue;
		nonzero:
			fat16bs = (struct fat16_boot_sector *) bp;
			if (fat16bs->s.media == 0xf8 &&
			    fat16bs->m.extd_signature == 0x29 &&
			    !strncmp(fat16bs->m.fs_name, "FAT", 3)) {
				int lth;
				lth = fat16bs->s.sectors[0] +
					fat16bs->s.sectors[1]*256;
				if (lth) {
					outmsg("small fat partition", i, i+lth, 0x1);
					addpart(i, lth, 0x1);
				} else {
					lth = fat16bs->s.total_sect;
					outmsg("fat partition", i, i+lth, 0x6);
					addpart(i, lth, 0x6);
				}
				i = i+lth-1;	/* skip */
				continue;
			}

			fat32bs = (struct fat32_boot_sector *) bp;
			if (fat32bs->s.media == 0xf8 &&
			    fat32bs->m.extd_signature == 0x29 &&
			    !strncmp(fat32bs->m.fs_name, "FAT32   ", 8)) {
				int lth = fat32bs->s.total_sect;
				outmsg("fat32 partition", i, i+lth, 0xb); /* or 0xc */
				addpart(i, lth, 0xb);
				i = i+lth-1;	/* skip */
				continue;
			}
		}

		if (!strncmp(bp+502, "SWAP-SPACE", 10)) {
			char *last;
			int ct;
			int ss = i-pagesecs+1;
			int es;
			char buf2[MAXPAGESZ];

			read_sectors(fd, buf2, ss, pagesecs);
			for (last = buf2+pagesize-10-1; last > buf2; last--)
				if (*last)
					break;
			for (ct = 7; ct >= 0; ct--)
				if (*last & (1<<ct))
					break;
			es = ((last - buf2)*8 + ct + 1)*pagesecs + ss;
			if (es <= size) {
				outmsg("old swap space", ss, es, 0x82);
				addpart(ss, es-ss, 0x82);

				i = es-1;	/* skip */
				continue;
			}
		}

		if (!strncmp(bp+502, "SWAPSPACE2", 10)) {
			int ss = i-pagesecs+1;
			int es, lth;
			char buf2[MAXPAGESZ];
			struct swap_header_v1 *p;

			read_sectors(fd, buf2, ss, pagesecs);
			p = (struct swap_header_v1 *) buf2;
			lth = (p->last_page + 1)* pagesecs;
			es = ss + lth;
			if (es <= size) {
				outmsg("new swap space", ss, es, 0x82);
				addpart(ss, lth, 0x82);

				i = es-1;       /* skip */
				continue;
			}
		}

		e2bp = (struct ext2_super_block *) bp;
		if (e2bp->s_magic == EXT2_SUPER_MAGIC && is_time(e2bp->s_mtime)
		    && is_time(e2bp->s_wtime) && is_ztime(e2bp->s_lastcheck)
		    && e2bp->s_log_block_size <= 10 /* at most 1 MB blocks */) {
			char buf[512];
			struct ext2_super_block *bp2;
			int ss, sz, es, gsz, j;

			ss = i-2;
			sz = (e2bp->s_blocks_count << (e2bp->s_log_block_size + 1));
			gsz = (e2bp->s_blocks_per_group << (e2bp->s_log_block_size + 1));
			if (e2bp->s_block_group_nr > 0)
				ss -= gsz * e2bp->s_block_group_nr;
			es = ss + sz;
			if (ss > 0 && es > i && es <= size) {
				if (e2bp->s_block_group_nr == 0) {
					outmsg("ext2 partition", ss, es, 0x83);
					addpart(ss, es-ss, 0x83);

					i = es-1;	/* skip */
					continue;
				}

				/* maybe we jumped into the middle of a partially
				   obliterated ext2 partition? */

				printf("# sector %d looks like an ext2 superblock copy #%d;\n"
				       "# in a partition covering sectors %d-%d\n",
				       i, e2bp->s_block_group_nr, ss, es-1);

				for (j=1; j<=e2bp->s_block_group_nr; j++) {
					read_sectors(fd, buf, i-j*gsz, 1);
					bp2 = (struct ext2_super_block *) buf;
					if (bp2->s_magic != EXT2_SUPER_MAGIC ||
					    bp2->s_block_group_nr !=
					      e2bp->s_block_group_nr - j)
						break;
				}
				if (j == 1)
					printf("# however, sector %d doesnt look like a sb.\n",
					       i-gsz);
				else if (j <= e2bp->s_block_group_nr)
					printf("# also the preceding %d block groups seem OK\n"
					       "# but before that things seem to be wrong.\n",
					       j-1);
				else {
					printf("# found all preceding superblocks OK\n"
					       "# Warning: overlapping partitions?\n");
					outmsg("ext2 partition", ss, es, 0x83);
					addpart(ss, es-ss, 0x83);
					i = es-1;       /* skip */
					continue;
				}
			}

		}

		if (bp[4] == 0x0d && bp[5] == 0x60 &&
		    bp[6] == 0x5e && bp[7] == 0xca &&   /* CA5E600D */
		    bp[156] == 0xee && bp[157] == 0xde &&
		    bp[158] == 0x0d && bp[159] == 0x60) /* 600DDEEE */ {
			int ss, es;
			struct unixware_slice *u;
			printf("# Unixware partition seen\n");
			u = (struct unixware_slice *)(bp + 216);
			if (u->slice_type == 5	/* entire disk */
			    && (u->slice_flags & 0x200)) /* valid */ {
				ss = u->start;
				es = u->start + u->size;
				outmsg("Unixware ptn", ss, es, 0x63);
				addpart(ss, es-ss, 0x63);
				i = es-1;
				continue;
			} else
				printf("# Unrecognized details\n");
		}

		/* bsd disk magic 0x82564557UL */
		if (bp[0] == 0x57 && bp[1] == 0x45 && bp[2] == 0x56 && bp[3] == 0x82) {
			int ss, es, npts, j;
			struct bsd_disklabel *l;
			struct bsd_partition *p;
			printf("# BSD magic seen in sector %d\n", i);
			l = (struct bsd_disklabel *) bp;
			if (l->d_magic2[0] != 0x57 || l->d_magic2[1] != 0x45 ||
			    l->d_magic2[2] != 0x56 || l->d_magic2[3] != 0x82)
				printf("# 2nd magic bad - ignored this sector\n");
			else if ((npts = l->d_npartitions) > 16)
				printf("# strange number (%d) of subpartitions - "
				       "ignored this sector\n", npts);
			else {
				for (j=0; j<npts; j++) {
					p = &(l->d_partitions[j]);
					if (p->p_size)
						printf("# part %c: size %9d, start %9d\n",
						       'a'+j, p->p_size, p->p_offset);
				}
				ss = l->d_partitions[2].p_offset;
				es = ss + l->d_partitions[2].p_size;
				if (ss != i-1)
					printf("# strange start of whole disk - "
					       "ignored this sector\n");
				else {
					/* FreeBSD 0xa5, OpenBSD 0xa6, NetBSD 0xa9, BSDI 0xb7 */
					/* How to distinguish? */
					outmsg("BSD partition", ss, es, 0xa5);
					addpart(ss, es-ss, 0xa5);
					i = es-1;
					continue;
				}
			}
		}
	}

	outparts();
	
	exit(0);
}