forked from sgan81/apfs-fuse
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDeviceMac.cpp
109 lines (84 loc) · 2.28 KB
/
DeviceMac.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/*
This file is part of apfs-fuse, a read-only implementation of APFS
(Apple File System) for FUSE.
Copyright (C) 2017 Simon Gander
Apfs-fuse is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
Apfs-fuse is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with apfs-fuse. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef __APPLE__
#include <unistd.h>
#include <sys/disk.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include "DeviceMac.h"
#include "Global.h"
DeviceMac::DeviceMac()
{
m_device = -1;
m_size = 0;
}
DeviceMac::~DeviceMac()
{
Close();
}
bool DeviceMac::Open(const char* name)
{
m_device = open(name, O_RDONLY);
if (m_device == -1)
{
std::cout << "Opening device " << name << " failed with error " << strerror(errno) << std::endl;
return false;
}
struct stat st;
fstat(m_device, &st);
std::cout << "st_mode = " << st.st_mode << std::endl;
if (S_ISREG(st.st_mode))
{
m_size = st.st_size;
}
else if (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode))
{
uint64_t sector_count = 0;
uint32_t sector_size = 0;
ioctl(m_device, DKIOCGETBLOCKCOUNT, §or_count);
ioctl(m_device, DKIOCGETBLOCKSIZE, §or_size);
m_size = sector_size * sector_count;
std::cout << "Sector count = " << sector_count << std::endl;
std::cout << "Sector size = " << sector_size << std::endl;
}
else
{
std::cout << "File mode unknown!" << std::endl;
}
if (g_debug & Dbg_Info)
std::cout << "Device " << name << " opened. Size is " << m_size << std::endl;
return m_device != -1;
}
void DeviceMac::Close()
{
if (m_device != -1)
close(m_device);
m_device = -1;
m_size = 0;
}
bool DeviceMac::Read(void* data, uint64_t offs, uint64_t len)
{
size_t nread;
nread = pread(m_device, data, len, offs);
// TODO: Better error handling ...
return nread == len;
}
#endif