2012-01-31 18 views
10

... başarıyla benim makinede bir ham diski açabiliyor değilim, ama diski uzunluğu aldığımda ben her seferinde 0 olsunAçık Ham Disk ve alın Boyutu OS X Aşağıdaki kodu kullanarak

// Where "Path" is /dev/rdisk1 -- is rdisk1 versus disk1 the proper way to open a raw disk? 
Device = open(Path, O_RDWR); 
if (Device == -1) 
{ 
    throw xException("Error opening device"); 
} 
bu yöntemlerin her ikisi ile

Ve alma boyutu 0 döndürür:

struct stat st; 

if (stat(Path, &st) == 0) 
    _Length = st.st_size; 

/

_Length = (INT64)lseek(Device, 0, SEEK_END); 
     lseek(Device, 0, SEEK_SET); 

ben olmayan Window üzerinde programlama ile tamamen aşina değilim platformlar, bu yüzden garip görünen her şeyi affet. Sorularım Buradasınız:

  1. bu OS X altında bir ham diski açmak için uygun yolu var mı?
  2. Disk boyutunun 0 olarak döndürülmesine neden olabilir?

söz konusu diskin bir biçimlendirilmemiş bir disk, ancak (kaldırıldı olmayan önemli şeylerle) Disk Utility gelen bilgi isteyenler için: ioctl talebi kodlarını arasında arama birazcık sonra

Name : ST920217 AS Media 
Type : Disk 

Partition Map Scheme : Unformatted 
Disk Identifier  : disk1 
Media Name   : ST920217 AS Media 
Media Type   : Generic 
Writable    : Yes 
Total Capacity  : 20 GB (20,003,880,960 Bytes) 
Disk Number   : 1 
Partition Number  : 0 
+0

Ham diske erişmenin iyi bir yolu olsa da, siz de fark ettiğiniz gibi çalışmayabilir (muhtemelen, önce lseek64'ü denemelisiniz). 'Ioctl' veya' fcntl' kullanarak boyutu elde etmek mümkün olabilir, aksi takdirde bazı özel OSX'e özgü fonksiyonlar aracılığıyla bilgi almak için başvurmalısınız. –

+0

@JoachimPileborg Peki ben _FILE_OFFSET_BITS 64 tanımlı var ... bunlar aynı davranmıyor mu? – Lander

+0

@JoachimPileborg yapıyor: 'lseek (Aygıt, 0x7FFFFFFF - 1, SEEK_SET)' aslında 0x7FFFFFFE değerini döndürür, bu nedenle ya bitler bırakılır veya diskler lseek (..., 0, SEEK_END); anlamak gerekir. edit: Neden lseek (Device, 0xFFFFFFFF + 5, SEEK_SET) 'i yapmadım bilmiyorum, ama bu 4 döndürür, bu yüzden bitlerin düştüğünü varsayardım. – Lander

cevap

8

Aslında işe yarayan bir şey buldum.

#include <sys/disk.h> 
#include <sys/ioctl.h> 
#include <fcntl.h> 

int main() 
{ 
    // Open disk 
    uint32_t dev = open("/dev/disk1", O_RDONLY); 

    if (dev == -1) { 
     perror("Failed to open disk"); 
     return -1; 
    } 

    uint64_t sector_count = 0; 
    // Query the number of sectors on the disk 
    ioctl(dev, DKIOCGETBLOCKCOUNT, &sector_count); 

    uint32_t sector_size = 0; 
    // Query the size of each sector 
    ioctl(dev, DKIOCGETBLOCKSIZE, &sector_size); 

    uint64_t disk_size = sector_count * sector_size; 
    printf("%ld", disk_size); 
    return 0; 
} 

Böyle bir şey hile yapmalıdır. Ben sadece içine aldığım kodu kopyaladım, bu yüzden tamam mı derleyeceğinden emin değilim ama yapmalı.

+0

Aslında bu gibi çalışmayacak - imzasız int Sektörlerin en azından imzasız olması gerekiyor Long, aksi takdirde ilk ioctl diğer yığın değişkenlerinin çöpe atılmasıyla sonuçlanır ("dev" varsayılan derleyici ayarlarıyla sıfırlanır ve makul bir küçük disk problanır)) Daha uygun, bu değişkenler sys veri yapıları gereği uint64_t ve uint32_t gerekir/disk.h – kert

+0

iyi yakalamak @kert, kodu güncelleyeceğiz. – Lander