1/* 2 * Copyright (c) 2008 Apple 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#include <TargetConditionals.h> 24#include <libc.h> 25#include <sys/stat.h> 26#include <dlfcn.h> 27#include "IOSystemConfiguration.h" 28 29 30#define SYSTEM_FRAMEWORK_DIR "/System/Library/Frameworks" 31#define SYSTEM_CONFIGURATION "SystemConfiguration.framework/SystemConfiguration" 32#define SC_FRAMEWORK SYSTEM_FRAMEWORK_DIR "/" SYSTEM_CONFIGURATION 33 34/* IOKIT_SC_SYMBOL 35 * 36 * - Tells the linker to pretend that _SYMBOL doesn't exist in OS X 10.7 and later. 37 * - Exports _SYMBOL as extern for OS X 38 * - Hides the _SYMBOL as __private_extern__ for iOS builds 39 * 40 */ 41#if TARGET_OS_IPHONE 42#define IOKIT_SC_SYMBOL(_RETURN, _SYMBOL) __private_extern__ _RETURN _io_##_SYMBOL 43#else 44#define IOKIT_SC_SYMBOL(_RETURN, _SYMBOL) extern const char _SYMBOL##_tmp7 __asm("$ld$hide$os10.7$_" #_SYMBOL ); \ 45 __attribute__ ((visibility("default"))) const char _SYMBOL##_tmp7 = 0; \ 46 _RETURN _SYMBOL 47#endif 48 49const CFStringRef _io_kSCCompAnyRegex = CFSTR("[^/]+"); 50const CFStringRef _io_kSCDynamicStoreDomainState = CFSTR("State:"); 51 52static void * symAddrInSC(const char *name) 53{ 54 static void * handle = NULL; 55 56 if (!handle) { 57 void *locHandle; 58 const char *framework = SC_FRAMEWORK; 59 struct stat statbuf; 60 const char *suffix = getenv("DYLD_IMAGE_SUFFIX"); 61 char path[MAXPATHLEN]; 62 63 strlcpy(path, framework, sizeof(path)); 64 65 if (suffix) { 66 strlcat(path, suffix, sizeof(path)); 67 } 68 69 if (0 <= stat(path, &statbuf)) { 70 locHandle = dlopen(path, RTLD_LAZY); 71 } else { 72 locHandle = dlopen(framework, RTLD_LAZY); 73 } 74 75 if (locHandle) { 76 handle = locHandle; 77 } 78 } 79 80 if (handle) 81 return dlsym(handle, name); 82 else 83 return NULL; 84} 85 86IOKIT_SC_SYMBOL(Boolean, SCDynamicStoreAddWatchedKey)( 87 SCDynamicStoreRef store, 88 CFStringRef key, 89 Boolean isRegex) 90{ 91 static typeof (SCDynamicStoreAddWatchedKey) *dyfunc; 92 if (!dyfunc) 93 dyfunc = symAddrInSC("SCDynamicStoreAddWatchedKey"); 94 95 if (dyfunc) 96 return (*dyfunc)(store, key, isRegex); 97 else 98 return false; 99} 100 101 102IOKIT_SC_SYMBOL(int, SCError)() 103{ 104 static typeof (SCError) *dyfunc; 105 if (!dyfunc) 106 dyfunc = symAddrInSC("SCError"); 107 if (dyfunc) 108 return (*dyfunc)(); 109 else 110 return kSCStatusFailed; 111} 112 113 114 115IOKIT_SC_SYMBOL(CFDictionaryRef, SCDynamicStoreCopyMultiple)( 116 SCDynamicStoreRef store, 117 CFArrayRef keys, 118 CFArrayRef patterns 119) 120{ 121 static typeof (SCDynamicStoreCopyMultiple) *dyfunc; 122 if (!dyfunc) 123 dyfunc = symAddrInSC("SCDynamicStoreCopyMultiple"); 124 if (dyfunc) 125 return (*dyfunc)(store, keys, patterns); 126 else 127 return NULL; 128} 129 130 131IOKIT_SC_SYMBOL(CFTypeRef, SCDynamicStoreCopyValue)( 132 SCDynamicStoreRef store, 133 CFStringRef key 134) 135{ 136 static typeof (SCDynamicStoreCopyValue) *dyfunc; 137 if (!dyfunc) 138 dyfunc = symAddrInSC("SCDynamicStoreCopyValue"); 139 if (dyfunc) 140 return (*dyfunc)(store, key); 141 else 142 return NULL; 143} 144 145 146IOKIT_SC_SYMBOL(SCDynamicStoreRef, SCDynamicStoreCreate)( 147 CFAllocatorRef allocator, 148 CFStringRef name, 149 SCDynamicStoreCallBack callout, 150 SCDynamicStoreContext *context 151) 152{ 153 static typeof (SCDynamicStoreCreate) *dyfunc; 154 if (!dyfunc) 155 dyfunc = symAddrInSC("SCDynamicStoreCreate"); 156 if (dyfunc) 157 return (*dyfunc)(allocator, name, callout, context); 158 else 159 return NULL; 160} 161 162 163IOKIT_SC_SYMBOL(CFRunLoopSourceRef, SCDynamicStoreCreateRunLoopSource)( 164 CFAllocatorRef allocator, 165 SCDynamicStoreRef store, 166 CFIndex order 167) 168{ 169 static typeof (SCDynamicStoreCreateRunLoopSource) *dyfunc; 170 if (!dyfunc) 171 dyfunc = symAddrInSC("SCDynamicStoreCreateRunLoopSource"); 172 if (dyfunc) 173 return (*dyfunc)(allocator, store, order); 174 else 175 return NULL; 176} 177 178 179IOKIT_SC_SYMBOL(CFStringRef, SCDynamicStoreKeyCreate)( 180 CFAllocatorRef allocator, 181 CFStringRef fmt, 182 ... 183) 184{ 185 // Local implementation of a SCDynamicStore wrapper function 186 va_list val; 187 188 va_start(val, fmt); 189 CFStringRef key = 190 CFStringCreateWithFormatAndArguments(allocator, NULL, fmt, val); 191 va_end(val); 192 193 return key; 194} 195 196 197IOKIT_SC_SYMBOL(CFStringRef, SCDynamicStoreKeyCreatePreferences)( 198 CFAllocatorRef allocator, 199 CFStringRef prefsID, 200 SCPreferencesKeyType keyType 201) 202{ 203 static typeof (SCDynamicStoreKeyCreatePreferences) *dyfunc; 204 if (!dyfunc) 205 dyfunc = symAddrInSC("SCDynamicStoreKeyCreatePreferences"); 206 if (dyfunc) 207 return (*dyfunc)(allocator, prefsID, keyType); 208 else 209 return NULL; 210} 211 212 213IOKIT_SC_SYMBOL(Boolean, SCDynamicStoreSetNotificationKeys)( 214 SCDynamicStoreRef store, 215 CFArrayRef keys, 216 CFArrayRef patterns 217) 218{ 219 static typeof (SCDynamicStoreSetNotificationKeys) *dyfunc; 220 if (!dyfunc) 221 dyfunc = symAddrInSC("SCDynamicStoreSetNotificationKeys"); 222 if (dyfunc) 223 return (*dyfunc)(store, keys, patterns); 224 else 225 return false; 226} 227 228 229IOKIT_SC_SYMBOL(Boolean, SCDynamicStoreNotifyValue)( 230 SCDynamicStoreRef store, 231 CFStringRef key 232) 233{ 234 static typeof (SCDynamicStoreNotifyValue) *dyfunc; 235 if (!dyfunc) 236 dyfunc = symAddrInSC("SCDynamicStoreNotifyValue"); 237 if (dyfunc) 238 return (*dyfunc)(store, key); 239 else 240 return false; 241} 242 243IOKIT_SC_SYMBOL(Boolean, SCDynamicStoreSetValue)( 244 SCDynamicStoreRef store, 245 CFStringRef key, 246 CFPropertyListRef value 247) 248{ 249 static typeof (SCDynamicStoreSetValue) *dyfunc; 250 if (!dyfunc) 251 dyfunc = symAddrInSC("SCDynamicStoreSetValue"); 252 if (dyfunc) 253 return (*dyfunc)(store, key, value); 254 else 255 return false; 256} 257 258 259IOKIT_SC_SYMBOL(Boolean, SCPreferencesApplyChanges)( 260 SCPreferencesRef prefs 261) 262{ 263 static typeof (SCPreferencesApplyChanges) *dyfunc; 264 if (!dyfunc) 265 dyfunc = symAddrInSC("SCPreferencesApplyChanges"); 266 if (dyfunc) 267 return (*dyfunc)(prefs); 268 else 269 return false; 270} 271 272 273IOKIT_SC_SYMBOL(Boolean, SCPreferencesCommitChanges)( 274 SCPreferencesRef prefs 275) 276{ 277 static typeof (SCPreferencesCommitChanges) *dyfunc; 278 if (!dyfunc) 279 dyfunc = symAddrInSC("SCPreferencesCommitChanges"); 280 if (dyfunc) 281 return (*dyfunc)(prefs); 282 else 283 return false; 284} 285 286 287IOKIT_SC_SYMBOL(SCPreferencesRef, SCPreferencesCreate)( 288 CFAllocatorRef allocator, 289 CFStringRef name, 290 CFStringRef prefsID 291) 292{ 293 static typeof (SCPreferencesCreate) *dyfunc; 294 if (!dyfunc) 295 dyfunc = symAddrInSC("SCPreferencesCreate"); 296 if (dyfunc) 297 return (*dyfunc)(allocator, name, prefsID); 298 else 299 return NULL; 300} 301 302 303IOKIT_SC_SYMBOL(SCPreferencesRef, SCPreferencesCreateWithAuthorization)( 304 CFAllocatorRef allocator, 305 CFStringRef name, 306 CFStringRef prefsID, 307 AuthorizationRef authorization 308) 309{ 310 static typeof (SCPreferencesCreateWithAuthorization) *dyfunc; 311 if (!dyfunc) 312 dyfunc = symAddrInSC("SCPreferencesCreateWithAuthorization"); 313 if (dyfunc) 314 return (*dyfunc)(allocator, name, prefsID, authorization); 315 else 316 return NULL; 317} 318 319 320IOKIT_SC_SYMBOL(CFPropertyListRef, SCPreferencesGetValue)( 321 SCPreferencesRef prefs, 322 CFStringRef key 323) 324{ 325 static typeof (SCPreferencesGetValue) *dyfunc; 326 if (!dyfunc) 327 dyfunc = symAddrInSC("SCPreferencesGetValue"); 328 if (dyfunc) 329 return (*dyfunc)(prefs, key); 330 else 331 return NULL; 332} 333 334 335IOKIT_SC_SYMBOL(Boolean, SCPreferencesLock)( 336 SCPreferencesRef prefs, 337 Boolean wait 338) 339{ 340 static typeof (SCPreferencesLock) *dyfunc; 341 if (!dyfunc) 342 dyfunc = symAddrInSC("SCPreferencesLock"); 343 if (dyfunc) 344 return (*dyfunc)(prefs, wait); 345 else 346 return false; 347} 348 349 350IOKIT_SC_SYMBOL(Boolean, SCPreferencesRemoveValue)( 351 SCPreferencesRef prefs, 352 CFStringRef key 353) 354{ 355 static typeof (SCPreferencesRemoveValue) *dyfunc; 356 if (!dyfunc) 357 dyfunc = symAddrInSC("SCPreferencesRemoveValue"); 358 if (dyfunc) 359 return (*dyfunc)(prefs, key); 360 else 361 return false; 362} 363 364 365IOKIT_SC_SYMBOL(Boolean, SCPreferencesSetValue)( 366 SCPreferencesRef prefs, 367 CFStringRef key, 368 CFPropertyListRef value 369) 370{ 371 static typeof (SCPreferencesSetValue) *dyfunc; 372 if (!dyfunc) 373 dyfunc = symAddrInSC("SCPreferencesSetValue"); 374 if (dyfunc) 375 return (*dyfunc)(prefs, key, value); 376 else 377 return false; 378} 379 380 381IOKIT_SC_SYMBOL(Boolean, SCPreferencesUnlock)( 382 SCPreferencesRef prefs 383) 384{ 385 static typeof (SCPreferencesUnlock) *dyfunc; 386 if (!dyfunc) 387 dyfunc = symAddrInSC("SCPreferencesUnlock"); 388 if (dyfunc) 389 return (*dyfunc)(prefs); 390 else 391 return false; 392} 393