2012-01-31 10 views
10

निम्नलिखित कोड का उपयोग करना, मैं सफलतापूर्वक मेरी मशीन पर एक कच्चे डिस्क खोलने में सक्षम हूँ, लेकिन जब मैं डिस्क लंबाई मिल रहा 0 हर बार मिलता है ...ओपन कच्चे डिस्क और जाओ आकार ओएस एक्स

// 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"); 
} 

और इन तरीकों में से दोनों के साथ हो रही आकार देता है 0:

struct stat st; 

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

/

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

मैं गैर-खिड़की पर प्रोग्रामिंग के साथ पूरी तरह से परिचित नहीं हूँ एस प्लेटफार्म, तो कृपया अजीब लगता है कि कुछ भी माफ कर दो। मेरे प्रश्न यहां हैं:

  1. क्या यह ओएस एक्स के तहत कच्ची डिस्क खोलने का उचित तरीका है?
  2. डिस्क आकार को 0 के रूप में वापस करने के कारण क्या हो सकता है?

सवाल में डिस्क एक अस्वरूपित डिस्क है, लेकिन (हटाया गैर महत्वपूर्ण सामग्री के साथ) डिस्क उपयोगिता से जानकारी चाहने वालों के लिए: के माध्यम से ioctl अनुरोध कोड

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

कच्चे डिस्क तक पहुंचने का एक अच्छा तरीका है, इस तरह के आकार को प्राप्त करने के रूप में आप काम नहीं कर सकते हैं (भी, आपको शायद 'lseek64' पहले कोशिश करनी चाहिए)। 'Ioctl' या' fcntl' का उपयोग करके आकार प्राप्त करना संभव हो सकता है, अन्यथा आपको कुछ विशेष ओएसएक्स-विशिष्ट फ़ंक्शन के माध्यम से जानकारी प्राप्त करने का सहारा लेना होगा। –

+0

@ जोचिमपाइलबॉर्ग ठीक है मेरे पास _FILE_OFFSET_BITS 64 परिभाषित है ... क्या यह वही कार्य नहीं करता है? – Lander

+0

@ जोचिमपिलबोर्ग कर रहे हैं: 'lseek (डिवाइस, 0x7FFFFFFF - 1, SEEK_SET)' वास्तव में 0x7FFFFFFE देता है, इसलिए या तो बिट्स को गिराया जा रहा है या डिस्क 'lseek (..., 0, SEEK_END) का समर्थन नहीं करते हैं;', लेकिन मेरे से उन्हें समझना चाहिए। संपादित करें: मुझे नहीं पता कि मैंने 'lseek (डिवाइस, 0xFFFFFFFF + 5, SEEK_SET) पहले नहीं किया था, लेकिन यह 4 लौटाता है, इसलिए मुझे लगता है कि बिट्स को गिराया जा रहा है। – Lander

उत्तर

8

खोज का एक छोटा सा के बाद , मुझे कुछ ऐसा लगता है जो वास्तव में काम करता है।

#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; 
} 

ऐसा कुछ ऐसा करना चाहिए। मैंने बस उस कोड को कॉपी किया है जिसमें मुझे था, इसलिए मुझे यकीन नहीं है कि यह ठीक से संकलित होगा लेकिन इसे चाहिए।

+0

दरअसल यह इस तरह काम नहीं करेगा - हस्ताक्षरित int सेक्टरों को कम से कम हस्ताक्षरित लंबे समय तक अनुमत होने की आवश्यकता है, अन्यथा पहले ioctl के परिणामस्वरूप अन्य स्टैक वैरिएबल ट्रैश किए जा रहे हैं ("dev" डिफ़ॉल्ट कंपाइलर सेटिंग्स के साथ शून्य पर लिखा जाता है और एक उचित छोटी डिस्क की जांच की जा रही है) अधिक उचित रूप से, इन चरों को sys/disk.h में डेटा संरचनाओं के अनुसार uint64_t और uint32_t होना चाहिए। – kert

+0

@ कर्ट अच्छी पकड़, मैं कोड अपडेट करूंगा। – Lander