2012-01-31 21 views
10

Sử dụng đoạn mã sau, tôi có thể mở thành công một đĩa liệu trên máy tính của tôi, nhưng khi tôi nhận được chiều dài đĩa tôi nhận được 0 mỗi lần ...mở Raw Disk và Nhận Kích OS X

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

Và nhận được kích thước với cả hai phương pháp trả về 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); 

tôi không hoàn toàn quen thuộc với lập trình trên phi Window s nền tảng, vì vậy xin vui lòng tha thứ cho bất cứ điều gì mà có vẻ kỳ lạ. Câu hỏi của tôi ở đây là:

  1. Đây có phải là cách thích hợp để mở đĩa thô dưới OS X không?
  2. Điều gì có thể khiến kích thước đĩa được trả lại là 0?

Đĩa trong câu hỏi là một đĩa chưa định dạng, nhưng đối với những người muốn thông tin từ Disk Utility (với những thứ không quan trọng loại bỏ):

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

Trong khi một cách tốt để truy cập vào đĩa thô, nhận được kích thước như vậy có thể không hoạt động như bạn nhận thấy (cũng có, bạn có lẽ nên thử 'lseek64' đầu tiên). Có thể có được kích thước bằng cách sử dụng 'ioctl' hoặc' fcntl', nếu không bạn phải sử dụng để nhận thông tin thông qua một số chức năng đặc biệt của OSX. –

+0

@JoachimPileborg Tôi có _FILE_OFFSET_BITS 64 được xác định ... những hành động này không giống nhau? – Lander

+0

@JoachimPileborg làm: 'lseek (Thiết bị, 0x7FFFFFFF - 1, SEEK_SET)' thực sự trả về 0x7FFFFFFE, do đó, một trong hai bit đang bị xóa hoặc đĩa không hỗ trợ 'lseek (..., 0, SEEK_END);', nhưng từ của tôi họ nên hiểu. chỉnh sửa: Tôi không biết tại sao tôi đã không làm 'lseek (Device, 0xFFFFFFFF + 5, SEEK_SET)' trước, nhưng điều đó trả về 4, vì vậy tôi giả định bit đang được giảm xuống. – Lander

Trả lời

8

Sau một chút tìm kiếm thông qua ioctl mã yêu cầu , Tôi tìm thấy một cái gì đó thực sự hoạt động.

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

Điều gì đó tương tự nên thực hiện thủ thuật. Tôi chỉ cần sao chép mã tôi đã có vào đó, vì vậy tôi không chắc chắn nếu nó sẽ biên dịch alright nhưng nó nên.

+0

Trên thực tế nó sẽ không hoạt động như thế - các unsigned int Sectors cần ít nhất là unsigned Long, nếu không ioctl đầu tiên sẽ dẫn đến các biến stack khác được chuyển vào thùng rác ("dev" được ghi bằng không với các thiết lập mặc định của trình biên dịch và một đĩa nhỏ hợp lý đang được thăm dò) Một cách thích hợp hơn, các biến này cần phải là uint64_t và uint32_t theo cấu trúc dữ liệu trong sys/disk.h – kert

+0

@kert bắt tốt, tôi sẽ cập nhật mã. – Lander