Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Open Raw Disk and Get Size OS X

Using the following code, I'm able to successfully open a raw disk on my machine, but when I get the disk length I get 0 each time...

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

And getting size with both of these methods returns 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);

I'm not totally familiar with programming on non-Windows platforms, so please forgive anything that seems odd. My questions here are:

  1. Is this the proper way to open a raw disk under OS X?
  2. What might be causing the disk size to be returned as 0?

The disk in question is an unformatted disk, but for those wanting the info from Disk Utility (with non-important stuff removed):

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
like image 956
Lander Avatar asked Jan 31 '12 02:01

Lander


1 Answers

After a little bit of searching through ioctl request codes, I found something that actually works.

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

Something like that should do the trick. I just copied the code I had into that, so I'm not sure if it would compile alright but it should.

like image 146
Lander Avatar answered Nov 15 '22 20:11

Lander