| 353 | } |
| 354 | |
| 355 | disk_t *hd_identify(const int verbose, const unsigned int disk, const int testdisk_mode) |
| 356 | { |
| 357 | unsigned char buf[0x200]; |
| 358 | memset(buf,0,sizeof(buf)); |
| 359 | /* standard BIOS access */ |
| 360 | if(biosdisk(8,disk,0,0,1,1,buf)) |
| 361 | return NULL; |
| 362 | if(verbose>1) |
| 363 | log_verbose("Disk %02X %u max %02X\n",disk,buf[2],(0x80+buf[2]-1)); |
| 364 | if(disk>(unsigned int)(0x80+buf[2]-1)) |
| 365 | return NULL; |
| 366 | { |
| 367 | char device[100]; |
| 368 | struct info_disk_struct*data=(struct info_disk_struct*)MALLOC(sizeof(*data)); |
| 369 | disk_t *disk_car=(disk_t *)MALLOC(sizeof(*disk_car)); |
| 370 | data->disk=disk; |
| 371 | data->bad_geometry=0; |
| 372 | data->mode_enh=0; |
| 373 | disk_car->arch=&arch_none; |
| 374 | snprintf(device,sizeof(device),"/dev/sda%u",disk); |
| 375 | disk_car->device=strdup(device); |
| 376 | disk_car->model=NULL; |
| 377 | disk_car->write_used=0; |
| 378 | disk_car->autodetect=0; |
| 379 | disk_car->sector_size=DEFAULT_SECTOR_SIZE; |
| 380 | disk_car->description=disk_description; |
| 381 | disk_car->description_short=disk_description_short; |
| 382 | disk_car->pread=disk_pread; |
| 383 | disk_car->pwrite=((testdisk_mode&TESTDISK_O_RDWR)==TESTDISK_O_RDWR?disk_pwrite:disk_nopwrite); |
| 384 | disk_car->sync=disk_sync; |
| 385 | disk_car->access_mode=testdisk_mode; |
| 386 | disk_car->clean=disk_clean; |
| 387 | disk_car->data=data; |
| 388 | disk_car->geom.cylinders=1+(((buf[0] & 0x0C0)<<2)|buf[1]); |
| 389 | disk_car->geom.heads_per_cylinder=1+buf[3]; |
| 390 | disk_car->geom.sectors_per_head=buf[0] & 0x3F; |
| 391 | if(disk_car->geom.heads_per_cylinder>255) |
| 392 | { /* Problem found by G Rowe */ |
| 393 | log_critical("BIOS reports an invalid heads number\n"); |
| 394 | data->bad_geometry=1; |
| 395 | disk_car->geom.heads_per_cylinder=255; |
| 396 | } |
| 397 | if(disk_car->geom.sectors_per_head==0) |
| 398 | { /* Problem found by Brian Barrett */ |
| 399 | log_critical("BIOS reports an invalid number of sectors per head\n"); |
| 400 | data->bad_geometry=1; |
| 401 | disk_car->geom.sectors_per_head=1; |
| 402 | } |
| 403 | disk_car->disk_size=(uint64_t)disk_car->geom.cylinders*disk_car->geom.heads_per_cylinder*disk_car->geom.sectors_per_head*disk_car->sector_size; |
| 404 | disk_car->disk_real_size=disk_car->disk_size; |
| 405 | data->geo_phys.cylinders=disk_car->geom.cylinders; |
| 406 | data->geo_phys.heads_per_cylinder=disk_car->geom.heads_per_cylinder; |
| 407 | data->geo_phys.sectors_per_head=disk_car->geom.sectors_per_head; |
| 408 | if(verbose>0) |
| 409 | log_info("%s\n",disk_description(disk_car)); |
| 410 | if(check_enh_bios(disk,verbose)) |
| 411 | { |
| 412 | /* enhanced BIOS access */ |
no test coverage detected