Skip to content

Latest commit

 

History

History
218 lines (169 loc) · 5.99 KB

physfs_platform_macos.c

File metadata and controls

218 lines (169 loc) · 5.99 KB
 
1
2
3
4
5
6
7
8
9
/*
* Mac OS X support routines for PhysicsFS.
*
* Please see the file LICENSE.txt in the source's root directory.
*
* This file written by Ryan C. Gordon.
*/
#define __PHYSICSFS_INTERNAL__
Jul 12, 2017
Jul 12, 2017
10
#include "physfs_internal.h"
11
12
13
#ifdef PHYSFS_PLATFORM_MACOSX
Jun 25, 2012
Jun 25, 2012
14
15
16
#include <CoreFoundation/CoreFoundation.h>
#if !defined(PHYSFS_NO_CDROM_SUPPORT)
Jul 12, 2017
Jul 12, 2017
17
#include <IOKit/IOKitLib.h>
18
19
20
21
#include <IOKit/storage/IOMedia.h>
#include <IOKit/storage/IOCDMedia.h>
#include <IOKit/storage/IODVDMedia.h>
#include <sys/mount.h>
Jun 25, 2012
Jun 25, 2012
22
23
#endif
24
25
int __PHYSFS_platformInit(void)
{
Jan 28, 2010
Jan 28, 2010
26
return 1; /* success. */
27
28
29
30
31
} /* __PHYSFS_platformInit */
int __PHYSFS_platformDeinit(void)
{
Jan 28, 2010
Jan 28, 2010
32
return 1; /* always succeed. */
33
34
35
} /* __PHYSFS_platformDeinit */
Jun 25, 2012
Jun 25, 2012
36
37
38
39
40
/* CD-ROM detection code... */
/*
* Code based on sample from Apple Developer Connection:
Feb 25, 2016
Feb 25, 2016
41
* https://developer.apple.com/samplecode/Sample_Code/Devices_and_Hardware/Disks/VolumeToBSDNode/VolumeToBSDNode.c.htm
Jun 25, 2012
Jun 25, 2012
44
45
#if !defined(PHYSFS_NO_CDROM_SUPPORT)
46
47
48
49
50
51
static int darwinIsWholeMedia(io_service_t service)
{
int retval = 0;
CFTypeRef wholeMedia;
if (!IOObjectConformsTo(service, kIOMediaClass))
Jan 28, 2010
Jan 28, 2010
52
return 0;
53
54
55
wholeMedia = IORegistryEntryCreateCFProperty(service,
CFSTR(kIOMediaWholeKey),
Jul 12, 2017
Jul 12, 2017
56
NULL, 0);
57
if (wholeMedia == NULL)
Jan 28, 2010
Jan 28, 2010
58
return 0;
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
retval = CFBooleanGetValue(wholeMedia);
CFRelease(wholeMedia);
return retval;
} /* darwinIsWholeMedia */
static int darwinIsMountedDisc(char *bsdName, mach_port_t masterPort)
{
int retval = 0;
CFMutableDictionaryRef matchingDict;
kern_return_t rc;
io_iterator_t iter;
io_service_t service;
if ((matchingDict = IOBSDNameMatching(masterPort, 0, bsdName)) == NULL)
Jan 28, 2010
Jan 28, 2010
76
return 0;
77
78
79
rc = IOServiceGetMatchingServices(masterPort, matchingDict, &iter);
if ((rc != KERN_SUCCESS) || (!iter))
Jan 28, 2010
Jan 28, 2010
80
return 0;
81
82
83
84
service = IOIteratorNext(iter);
IOObjectRelease(iter);
if (!service)
Jan 28, 2010
Jan 28, 2010
85
return 0;
86
87
88
89
90
rc = IORegistryEntryCreateIterator(service, kIOServicePlane,
kIORegistryIterateRecursively | kIORegistryIterateParents, &iter);
if (!iter)
Jan 28, 2010
Jan 28, 2010
91
return 0;
92
93
94
95
if (rc != KERN_SUCCESS)
{
IOObjectRelease(iter);
Jan 28, 2010
Jan 28, 2010
96
return 0;
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
} /* if */
IOObjectRetain(service); /* add an extra object reference... */
do
{
if (darwinIsWholeMedia(service))
{
if ( (IOObjectConformsTo(service, kIOCDMediaClass)) ||
(IOObjectConformsTo(service, kIODVDMediaClass)) )
{
retval = 1;
} /* if */
} /* if */
IOObjectRelease(service);
} while ((service = IOIteratorNext(iter)) && (!retval));
IOObjectRelease(iter);
IOObjectRelease(service);
Jan 28, 2010
Jan 28, 2010
117
return retval;
118
119
} /* darwinIsMountedDisc */
Jun 25, 2012
Jun 25, 2012
120
121
#endif /* !defined(PHYSFS_NO_CDROM_SUPPORT) */
122
123
124
void __PHYSFS_platformDetectAvailableCDs(PHYSFS_StringCallback cb, void *data)
{
Jun 25, 2012
Jun 25, 2012
125
#if !defined(PHYSFS_NO_CDROM_SUPPORT)
126
127
128
129
130
131
132
const char *devPrefix = "/dev/";
const int prefixLen = strlen(devPrefix);
mach_port_t masterPort = 0;
struct statfs *mntbufp;
int i, mounts;
if (IOMasterPort(MACH_PORT_NULL, &masterPort) != KERN_SUCCESS)
Jul 6, 2017
Jul 6, 2017
133
BAIL(PHYSFS_ERR_OS_ERROR, ) /*return void*/;
134
135
136
137
138
139
140
141
142
143
144
145
146
mounts = getmntinfo(&mntbufp, MNT_WAIT); /* NOT THREAD SAFE! */
for (i = 0; i < mounts; i++)
{
char *dev = mntbufp[i].f_mntfromname;
char *mnt = mntbufp[i].f_mntonname;
if (strncmp(dev, devPrefix, prefixLen) != 0) /* a virtual device? */
continue;
dev += prefixLen;
if (darwinIsMountedDisc(dev, masterPort))
cb(data, mnt);
} /* for */
Jun 25, 2012
Jun 25, 2012
147
#endif /* !defined(PHYSFS_NO_CDROM_SUPPORT) */
148
149
150
151
152
153
154
155
} /* __PHYSFS_platformDetectAvailableCDs */
static char *convertCFString(CFStringRef cfstr)
{
CFIndex len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(cfstr),
kCFStringEncodingUTF8) + 1;
char *retval = (char *) allocator.Malloc(len);
Jul 6, 2017
Jul 6, 2017
156
BAIL_IF(!retval, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
if (CFStringGetCString(cfstr, retval, len, kCFStringEncodingUTF8))
{
/* shrink overallocated buffer if possible... */
CFIndex newlen = strlen(retval) + 1;
if (newlen < len)
{
void *ptr = allocator.Realloc(retval, newlen);
if (ptr != NULL)
retval = (char *) ptr;
} /* if */
} /* if */
else /* probably shouldn't fail, but just in case... */
{
allocator.Free(retval);
Jul 6, 2017
Jul 6, 2017
173
BAIL(PHYSFS_ERR_OUT_OF_MEMORY, NULL);
Jan 28, 2010
Jan 28, 2010
176
return retval;
177
178
179
180
181
182
183
184
185
186
} /* convertCFString */
char *__PHYSFS_platformCalcBaseDir(const char *argv0)
{
CFURLRef cfurl = NULL;
CFStringRef cfstr = NULL;
CFMutableStringRef cfmutstr = NULL;
char *retval = NULL;
Jun 25, 2012
Jun 25, 2012
187
cfurl = CFBundleCopyBundleURL(CFBundleGetMainBundle());
Jul 6, 2017
Jul 6, 2017
188
BAIL_IF(cfurl == NULL, PHYSFS_ERR_OS_ERROR, NULL);
189
190
cfstr = CFURLCopyFileSystemPath(cfurl, kCFURLPOSIXPathStyle);
CFRelease(cfurl);
Jul 6, 2017
Jul 6, 2017
191
BAIL_IF(!cfstr, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
Jul 12, 2017
Jul 12, 2017
192
cfmutstr = CFStringCreateMutableCopy(NULL, 0, cfstr);
Jul 6, 2017
Jul 6, 2017
194
BAIL_IF(!cfmutstr, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
Jun 25, 2012
Jun 25, 2012
195
CFStringAppendCString(cfmutstr, "/", kCFStringEncodingUTF8);
196
197
198
retval = convertCFString(cfmutstr);
CFRelease(cfmutstr);
Jan 28, 2010
Jan 28, 2010
199
return retval; /* whew. */
200
201
202
} /* __PHYSFS_platformCalcBaseDir */
Mar 22, 2012
Mar 22, 2012
203
204
205
206
207
char *__PHYSFS_platformCalcPrefDir(const char *org, const char *app)
{
/* !!! FIXME: there's a real API to determine this */
const char *userdir = __PHYSFS_getUserDir();
const char *append = "Library/Application Support/";
Mar 22, 2012
Mar 22, 2012
208
const size_t len = strlen(userdir) + strlen(append) + strlen(app) + 2;
Mar 22, 2012
Mar 22, 2012
209
char *retval = allocator.Malloc(len);
Jul 6, 2017
Jul 6, 2017
210
BAIL_IF(!retval, PHYSFS_ERR_OUT_OF_MEMORY, NULL);
Mar 22, 2012
Mar 22, 2012
211
snprintf(retval, len, "%s%s%s/", userdir, append, app);
Mar 22, 2012
Mar 22, 2012
212
213
214
return retval;
} /* __PHYSFS_platformCalcPrefDir */
215
216
#endif /* PHYSFS_PLATFORM_MACOSX */
Jul 22, 2017
Jul 22, 2017
217
/* end of physfs_platform_macos.c ... */