]>
Commit | Line | Data |
---|---|---|
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 | } |