3
// Copyright (c) 2009 Romain Tartière <romain@blogreen.org>
5
// Permission is hereby granted, free of charge, to any person obtaining a copy
6
// of this software and associated documentation files (the "Software"), to deal
7
// in the Software without restriction, including without limitation the rights
8
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
// copies of the Software, and to permit persons to whom the Software is
10
// furnished to do so, subject to the following conditions:
12
// The above copyright notice and this permission notice shall be included in
13
// all copies or substantial portions of the Software.
15
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
using System.Runtime.InteropServices;
28
internal sealed class DiscFreeBsd : LocalDisc
32
// open for reading only
33
const int O_RDONLY = 0x0000;
35
const int O_NONBLOCK = 0x0004;
37
[DllImport ("libc", CharSet = CharSet.Auto, SetLastError = true)]
38
static extern int open (string path, int flags);
42
[DllImport ("libc", SetLastError = true)]
43
static extern int close (int d);
49
public int lba; // network byte order
52
[StructLayout (LayoutKind.Explicit)]
61
// Ioctls for the CD drive
63
const byte CD_LBA_FORMAT = 1;
68
public byte starting_track;
69
public byte ending_track;
71
const ulong CDIOREADTOCHEADER = 1074029316;
72
[DllImport ("libc", EntryPoint = "ioctl")]
73
static extern int cd_read_toc_header (int fd, ulong request, ref ioc_toc_header data);
74
static int cd_read_toc_header (int fd, ref ioc_toc_header data)
76
return cd_read_toc_header (fd, CDIOREADTOCHEADER, ref data);
79
struct ioc_read_toc_entry
81
public byte address_format;
82
public byte starting_track;
83
public ushort data_len;
84
public IntPtr data; // cd_toc_entry*
86
const ulong CDIOREADTOCENTRYS = 3222299397;
87
[DllImport ("libc", EntryPoint = "ioctl")]
88
static extern int cd_read_toc_entrys (int fd, ulong request, ref ioc_read_toc_entry data);
89
static int cd_read_toc_entrys (int fd, ref ioc_read_toc_entry data)
91
return cd_read_toc_entrys (fd, CDIOREADTOCENTRYS, ref data);
96
internal DiscFreeBsd (string device)
98
int fd = open (device, O_RDONLY | O_NONBLOCK);
101
throw new LocalDiscException (String.Format ("Cannot open device `{0}'", device));
105
ioc_toc_header h = new ioc_toc_header ();
106
if (cd_read_toc_header (fd, ref h) < 0) {
107
throw new LocalDiscException ("Cannot read table of contents header");
109
if (h.ending_track == 0) {
110
throw new LocalDiscException ("This disc has no tracks");
113
first_track = h.starting_track;
114
last_track = h.ending_track;
116
int n = h.ending_track - h.starting_track + 1;
117
int len = (n + 1) * Marshal.SizeOf (typeof (cd_toc_entry));
119
ioc_read_toc_entry t = new ioc_read_toc_entry ();
120
t.address_format = CD_LBA_FORMAT;
121
t.starting_track = 0;
122
t.data_len = (ushort) len;
123
t.data = Marshal.AllocHGlobal (len);
126
if (cd_read_toc_entrys (fd, ref t) < 0) {
127
throw new LocalDiscException ("Cannot read table of contents entries");
130
for (int i = 0; i <= n; i++) {
131
ulong offset = (ulong) (i * Marshal.SizeOf (typeof (cd_toc_entry)));
132
cd_toc_entry e = (cd_toc_entry) Marshal.PtrToStructure ((IntPtr) ((ulong)t.data + offset), typeof (cd_toc_entry));
133
track_offsets[first_track + i] = System.Net.IPAddress.NetworkToHostOrder (e.addr.lba) + 150;
136
// Move Leadout to the beginning.
137
track_offsets [0] = track_offsets [last_track + 1];
138
track_offsets [last_track + 1] = 0;
140
Marshal.FreeHGlobal (t.data);