]> git.saurik.com Git - apple/hfs.git/blob - mount_hfs/optical.c
hfs-366.70.1.tar.gz
[apple/hfs.git] / mount_hfs / optical.c
1 /*
2 * Copyright (c) 2007 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 #include "optical.h"
25
26 #include <paths.h>
27 #include <string.h>
28 #include <CoreFoundation/CoreFoundation.h>
29 #include <IOKit/IOKitLib.h>
30 #include <IOKit/storage/IOMedia.h>
31 #include <IOKit/storage/IOBDMedia.h>
32 #include <IOKit/storage/IOCDMedia.h>
33 #include <IOKit/storage/IODVDMedia.h>
34
35 static io_service_t
36 __io_media_copy_whole_media(io_service_t media)
37 {
38 io_service_t parent;
39 CFTypeRef property;
40
41 IOObjectRetain(media);
42
43 while (media) {
44 if (IOObjectConformsTo(media, kIOMediaClass)) {
45 property = IORegistryEntryCreateCFProperty(media, CFSTR(kIOMediaWholeKey), kCFAllocatorDefault, 0);
46 if (property) {
47 CFRelease(property);
48 if (property == kCFBooleanTrue)
49 break;
50 }
51 }
52 parent = IO_OBJECT_NULL;
53 IORegistryEntryGetParentEntry(media, kIOServicePlane, &parent);
54 IOObjectRelease(media);
55 media = parent;
56 }
57
58 return media;
59 }
60
61 static io_service_t
62 __io_media_create_from_bsd_name(const char *name)
63 {
64 if (!strncmp(_PATH_DEV, name, strlen(_PATH_DEV)))
65 name += strlen(_PATH_DEV);
66
67 return IOServiceGetMatchingService(kIOMasterPortDefault, IOBSDNameMatching(kIOMasterPortDefault, 0, name));
68 }
69
70 static int
71 __io_media_is_writable(io_service_t media)
72 {
73 int writable = 0;
74 CFTypeRef property;
75
76 property = IORegistryEntryCreateCFProperty(media, CFSTR(kIOMediaWritableKey), kCFAllocatorDefault, 0);
77 if (property) {
78 CFRelease(property);
79 if (property == kCFBooleanTrue) {
80 writable = _OPTICAL_WRITABLE_SECTOR;
81
82 if (IOObjectConformsTo(media, kIOBDMediaClass)) {
83 property = IORegistryEntryCreateCFProperty(media, CFSTR(kIOBDMediaTypeKey), kCFAllocatorDefault, 0);
84 if (property) {
85 if (CFEqual(property, CFSTR(kIOBDMediaTypeR)))
86 writable = _OPTICAL_WRITABLE_PACKET | _OPTICAL_WRITABLE_ONCE; /* BD-R */
87 else if (CFEqual(property, CFSTR(kIOBDMediaTypeRE)))
88 writable = _OPTICAL_WRITABLE_PACKET; /* BD-RE */
89 CFRelease(property);
90 }
91 } else if (IOObjectConformsTo(media, kIOCDMediaClass)) {
92 property = IORegistryEntryCreateCFProperty(media, CFSTR(kIOCDMediaTypeKey), kCFAllocatorDefault, 0);
93 if (property) {
94 if (CFEqual(property, CFSTR(kIOCDMediaTypeR)))
95 writable = _OPTICAL_WRITABLE_PACKET | _OPTICAL_WRITABLE_ONCE; /* CD-R */
96 else if (CFEqual(property, CFSTR(kIOCDMediaTypeRW)))
97 writable = _OPTICAL_WRITABLE_PACKET; /* CD-RW */
98
99 CFRelease(property);
100 }
101 } else if (IOObjectConformsTo(media, kIODVDMediaClass)) {
102 property = IORegistryEntryCreateCFProperty(media, CFSTR(kIODVDMediaTypeKey), kCFAllocatorDefault, 0);
103 if (property) {
104 if (CFEqual(property, CFSTR(kIODVDMediaTypeR)))
105 writable = _OPTICAL_WRITABLE_PACKET | _OPTICAL_WRITABLE_ONCE; /* DVD-R */
106 else if (CFEqual(property, CFSTR(kIODVDMediaTypeRW)))
107 writable = _OPTICAL_WRITABLE_PACKET; /* DVD-RW */
108 else if (CFEqual(property, CFSTR(kIODVDMediaTypePlusR)))
109 writable = _OPTICAL_WRITABLE_PACKET | _OPTICAL_WRITABLE_ONCE; /* DVD+R */
110 else if (CFEqual(property, CFSTR(kIODVDMediaTypePlusRW)))
111 writable = _OPTICAL_WRITABLE_PACKET; /* DVD+RW */
112 else if (CFEqual(property, CFSTR(kIODVDMediaTypeHDR)))
113 writable = _OPTICAL_WRITABLE_PACKET | _OPTICAL_WRITABLE_ONCE; /* HD DVD-R */
114
115 CFRelease(property);
116 }
117 }
118 }
119 }
120
121 return writable;
122 }
123
124 int
125 _optical_is_writable(const char *dev)
126 {
127 int writable = 0;
128 io_service_t media;
129 io_service_t whole;
130
131 media = __io_media_create_from_bsd_name(dev);
132 if (media) {
133 writable = __io_media_is_writable(media);
134 if (writable) {
135 whole = __io_media_copy_whole_media(media);
136 if (whole) {
137 writable = __io_media_is_writable(whole);
138
139 IOObjectRelease(whole);
140 }
141 }
142 IOObjectRelease(media);
143 }
144
145 return writable;
146 }