]> git.saurik.com Git - apple/xnu.git/blob - libkern/libkern/OSKextLib.h
6ecc3548d7f0f7bc7c8595e6e711df5fe56fb14a
[apple/xnu.git] / libkern / libkern / OSKextLib.h
1 /*
2 * Copyright (c) 2008 Apple Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_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. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29 #ifndef _LIBKERN_OSKEXTLIB_H
30 #define _LIBKERN_OSKEXTLIB_H
31
32 #include <sys/cdefs.h>
33 __BEGIN_DECLS
34
35 #include <stdint.h>
36 #include <mach/kmod.h>
37 #include <mach/vm_types.h>
38
39 #ifdef KERNEL
40 #include <libkern/OSTypes.h>
41 #include <libkern/OSReturn.h>
42 #else
43 #include <CoreFoundation/CoreFoundation.h>
44 #include <System/libkern/OSReturn.h>
45 #endif /* KERNEL */
46
47 /*!
48 * @header
49 *
50 * Declares functions, basic return values, and other constants
51 * related to kernel extensions (kexts).
52 */
53
54 #if PRAGMA_MARK
55 #pragma mark -
56 /********************************************************************/
57 #pragma mark OSReturn Values for Kernel Extensions
58 /********************************************************************/
59 #endif
60 /*!
61 * @group OSReturn Values for Kernel Extensions
62 * Many kext-related functions return these values,
63 * as well as those defined under
64 * <code>@link //apple_ref/c/tdef/OSReturn OSReturn@/link</code>
65 * and other variants of <code>kern_return_t</code>.
66 */
67
68 #ifdef XNU_KERNEL_PRIVATE
69 /*********************************************************************
70 * Check libsyscall/mach/err_libkern.sub when editing or adding
71 * result codes!
72 *********************************************************************/
73 #endif /* XNU_KERNEL_PRIVATE */
74
75 #define sub_libkern_kext err_sub(2)
76 #define libkern_kext_err(code) (sys_libkern|sub_libkern_kext|(code))
77
78
79 /*!
80 * @define kOSKextReturnInternalError
81 * @abstract An internal error in the kext library.
82 * Contrast with <code>@link //apple_ref/c/econst/OSReturnError
83 * OSReturnError@/link</code>.
84 */
85 #define kOSKextReturnInternalError libkern_kext_err(0x1)
86
87 /*!
88 * @define kOSKextReturnNoMemory
89 * @abstract Memory allocation failed.
90 */
91 #define kOSKextReturnNoMemory libkern_kext_err(0x2)
92
93 /*!
94 * @define kOSKextReturnNoResources
95 * @abstract Some resource other than memory (such as available load tags)
96 * is exhausted.
97 */
98 #define kOSKextReturnNoResources libkern_kext_err(0x3)
99
100 /*!
101 * @define kOSKextReturnNotPrivileged
102 * @abstract The caller lacks privileges to perform the requested operation.
103 */
104 #define kOSKextReturnNotPrivileged libkern_kext_err(0x4)
105
106 /*!
107 * @define kOSKextReturnInvalidArgument
108 * @abstract Invalid argument.
109 */
110 #define kOSKextReturnInvalidArgument libkern_kext_err(0x5)
111
112 /*!
113 * @define kOSKextReturnNotFound
114 * @abstract Search item not found.
115 */
116 #define kOSKextReturnNotFound libkern_kext_err(0x6)
117
118 /*!
119 * @define kOSKextReturnBadData
120 * @abstract Malformed data (not used for XML).
121 */
122 #define kOSKextReturnBadData libkern_kext_err(0x7)
123
124 /*!
125 * @define kOSKextReturnSerialization
126 * @abstract Error converting or (un)serializing URL, string, or XML.
127 */
128 #define kOSKextReturnSerialization libkern_kext_err(0x8)
129
130 /*!
131 * @define kOSKextReturnUnsupported
132 * @abstract Operation is no longer or not yet supported.
133 */
134 #define kOSKextReturnUnsupported libkern_kext_err(0x9)
135
136 /*!
137 * @define kOSKextReturnDisabled
138 * @abstract Operation is currently disabled.
139 */
140 #define kOSKextReturnDisabled libkern_kext_err(0xa)
141
142 /*!
143 * @define kOSKextReturnNotAKext
144 * @abstract Bundle is not a kernel extension.
145 */
146 #define kOSKextReturnNotAKext libkern_kext_err(0xb)
147
148 /*!
149 * @define kOSKextReturnValidation
150 * @abstract Validation failures encountered; check diagnostics for details.
151 */
152 #define kOSKextReturnValidation libkern_kext_err(0xc)
153
154 /*!
155 * @define kOSKextReturnAuthentication
156 * @abstract Authetication failures encountered; check diagnostics for details.
157 */
158 #define kOSKextReturnAuthentication libkern_kext_err(0xd)
159
160 /*!
161 * @define kOSKextReturnDependencies
162 * @abstract Dependency resolution failures encountered; check diagnostics for details.
163 */
164 #define kOSKextReturnDependencies libkern_kext_err(0xe)
165
166 /*!
167 * @define kOSKextReturnArchNotFound
168 * @abstract Kext does not contain code for the requested architecture.
169 */
170 #define kOSKextReturnArchNotFound libkern_kext_err(0xf)
171
172 /*!
173 * @define kOSKextReturnCache
174 * @abstract An error occurred processing a system kext cache.
175 */
176 #define kOSKextReturnCache libkern_kext_err(0x10)
177
178 /*!
179 * @define kOSKextReturnDeferred
180 * @abstract Operation has been posted asynchronously to user space (kernel only).
181 */
182 #define kOSKextReturnDeferred libkern_kext_err(0x11)
183
184 /*!
185 * @define kOSKextReturnBootLevel
186 * @abstract Kext not loadable or operation not allowed at current boot level.
187 */
188 #define kOSKextReturnBootLevel libkern_kext_err(0x12)
189
190 /*!
191 * @define kOSKextReturnNotLoadable
192 * @abstract Kext cannot be loaded; check diagnostics for details.
193 */
194 #define kOSKextReturnNotLoadable libkern_kext_err(0x13)
195
196 /*!
197 * @define kOSKextReturnLoadedVersionDiffers
198 * @abstract A different version (or executable UUID, or executable by checksum)
199 * of the requested kext is already loaded.
200 */
201 #define kOSKextReturnLoadedVersionDiffers libkern_kext_err(0x14)
202
203 /*!
204 * @define kOSKextReturnDependencyLoadError
205 * @abstract A load error occurred on a dependency of the kext being loaded.
206 */
207 #define kOSKextReturnDependencyLoadError libkern_kext_err(0x15)
208
209 /*!
210 * @define kOSKextReturnLinkError
211 * @abstract A link failure occured with this kext or a dependency.
212 */
213 #define kOSKextReturnLinkError libkern_kext_err(0x16)
214
215 /*!
216 * @define kOSKextReturnStartStopError
217 * @abstract The kext start or stop routine returned an error.
218 */
219 #define kOSKextReturnStartStopError libkern_kext_err(0x17)
220
221 /*!
222 * @define kOSKextReturnInUse
223 * @abstract The kext is currently in use or has outstanding references,
224 * and cannot be unloaded.
225 */
226 #define kOSKextReturnInUse libkern_kext_err(0x18)
227
228 /*!
229 * @define kOSKextReturnTimeout
230 * @abstract A kext request has timed out.
231 */
232 #define kOSKextReturnTimeout libkern_kext_err(0x19)
233
234 /*!
235 * @define kOSKextReturnStopping
236 * @abstract The kext is in the process of stopping; requests cannot be made.
237 */
238 #define kOSKextReturnStopping libkern_kext_err(0x1a)
239
240 #if PRAGMA_MARK
241 #pragma mark -
242 /********************************************************************/
243 #pragma mark Kext/OSBundle Property List Keys
244 /********************************************************************/
245 #endif
246 /*!
247 * @group Kext Property List Keys
248 * These constants cover CFBundle properties defined for kernel extensions.
249 * Because they are used in the kernel, if you want to use one with
250 * CFBundle APIs you'll need to wrap it in a <code>CFSTR()</code> macro.
251 */
252
253 #ifdef KERNEL
254 /* Define C-string versions of the CFBundle keys for use in the kernel.
255 */
256 #define kCFBundleIdentifierKey "CFBundleIdentifier"
257 #define kCFBundleVersionKey "CFBundleVersion"
258 #define kCFBundleNameKey "CFBundleName"
259 #define kCFBundleExecutableKey "CFBundleExecutable"
260 #endif /* KERNEL */
261
262 /*!
263 * @define kOSBundleCompatibleVersionKey
264 * @abstract A string giving the backwards-compatible version of a library kext
265 * in extended Mac OS 'vers' format (####.##.##s{1-255} where 's'
266 * is a build stage 'd', 'a', 'b', 'f' or 'fc').
267 */
268 #define kOSBundleCompatibleVersionKey "OSBundleCompatibleVersion"
269
270 /*!
271 * @define kOSBundleEnableKextLoggingKey
272 * @abstract Set to true to have the kernel kext logging spec applied
273 * to the kext.
274 * See <code>@link //apple_ref/c/econst/OSKextLogSpec
275 * OSKextLogSpec@/link</code>.
276 */
277 #define kOSBundleEnableKextLoggingKey "OSBundleEnableKextLogging"
278
279 /*!
280 * @define kOSBundleIsInterfaceKey
281 * @abstract A boolean value indicating whether the kext executable
282 * contains only symbol references.
283 */
284 #define kOSBundleIsInterfaceKey "OSBundleIsInterface"
285
286 /*!
287 * @define kOSBundleLibrariesKey
288 * @abstract A dictionary listing link dependencies for this kext.
289 * Keys are bundle identifiers, values are version strings.
290 */
291 #define kOSBundleLibrariesKey "OSBundleLibraries"
292
293 /*!
294 * @define kOSBundleRequiredKey
295 * @abstract A string indicating in which kinds of startup this kext
296 * may need to load during early startup (before
297 * <code>@link //apple_ref/doc/man/8/kextd kextcache(8)@/link</code>).
298 * @discussion
299 * The value is one of:
300 * <ul>
301 * <li>@link kOSBundleRequiredRoot "OSBundleRequiredRoot"@/link</li>
302 * <li>@link kOSBundleRequiredLocalRoot "OSBundleRequiredLocalRoot"@/link</li>
303 * <li>@link kOSBundleRequiredNetworkRoot "OSBundleRequiredNetworkRoot"@/link</li>
304 * <li>@link kOSBundleRequiredSafeBoot "OSBundleRequiredSafeBoot"@/link</li>
305 * <li>@link kOSBundleRequiredConsole "OSBundleRequiredConsole"@/link</li>
306 * </ul>
307 *
308 * Use this property judiciously.
309 * Every kext that declares a value other than "OSBundleRequiredSafeBoot"
310 * increases startup time, as the booter must read it into memory,
311 * or startup kext caches must include it.
312 */
313 #define kOSBundleRequiredKey "OSBundleRequired"
314
315 /*!
316 * @define kOSBundleAllowUserLoadKey
317 * @abstract A boolean value indicating whether
318 * <code>@link //apple_ref/doc/man/8/kextd kextcache(8)@/link</code>
319 * will honor a non-root process's request to load a kext.
320 * @discussion
321 * See <code>@link //apple_ref/doc/compositePage/c/func/KextManagerLoadKextWithURL
322 * KextManagerLoadKextWithURL@/link</code>
323 * and <code>@link //apple_ref/doc/compositePage/c/func/KextManagerLoadKextWithIdentifier
324 * KextManagerLoadKextWithIdentifier@/link</code>.
325 */
326 #define kOSBundleAllowUserLoadKey "OSBundleAllowUserLoad"
327
328 /*!
329 * @define kOSKernelResourceKey
330 * @abstract A boolean value indicating whether the kext represents a built-in
331 * component of the kernel.
332 */
333 #define kOSKernelResourceKey "OSKernelResource"
334
335 /*!
336 * @define kIOKitPersonalitiesKey
337 * @abstract A dictionary of dictionaries used in matching for I/O Kit drivers.
338 */
339 #define kIOKitPersonalitiesKey "IOKitPersonalities"
340
341 /*
342 * @define kIOPersonalityPublisherKey
343 * @abstract Used in personalities sent to the I/O Kit,
344 * contains the CFBundleIdentifier of the kext
345 * that the personality originated in.
346 */
347 #define kIOPersonalityPublisherKey "IOPersonalityPublisher"
348
349
350 #if PRAGMA_MARK
351 /********************************************************************/
352 #pragma mark Kext/OSBundle Property Deprecated Keys
353 /********************************************************************/
354 #endif
355 /*
356 * @define kOSBundleDebugLevelKey
357 * @abstract
358 * Deprecated (used on some releases of Mac OS X prior to 10.6 Snow Leopard).
359 * Value is an integer from 1-6, corresponding to the verbose levels
360 * of kext tools on those releases.
361 * On 10.6 Snow Leopard, use <code>@link OSKextEnableKextLogging
362 * OSKextEnableKextLogging@/link</code>.
363 */
364 #define kOSBundleDebugLevelKey "OSBundleDebugLevel"
365
366 /*!
367 * @define kOSBundleSharedExecutableIdentifierKey
368 * @abstract Deprecated (used on some releases of Mac OS X
369 * prior to 10.6 Snow Leopard).
370 * Value is the bundle identifier of the pseudokext
371 * that contains an executable shared by this kext.
372 */
373 #define kOSBundleSharedExecutableIdentifierKey "OSBundleSharedExecutableIdentifier"
374
375
376 #if PRAGMA_MARK
377 /********************************************************************/
378 #pragma mark Kext/OSBundle Property List Values
379 /********************************************************************/
380 #endif
381
382 /*!
383 * @group Kext Property List Values
384 * These constants encompass established values
385 * for kernel extension bundle properties.
386 */
387
388 /*!
389 * @define kOSKextKernelIdentifier
390 * @abstract
391 * This is the CFBundleIdentifier user for the kernel itself.
392 */
393 #define kOSKextKernelIdentifier "__kernel__"
394
395 /*!
396 * @define kOSBundleRequiredRoot
397 * @abstract
398 * This <code>@link kOSBundleRequiredKey OSBundleRequired@/link</code>
399 * value indicates that the kext may be needed to mount the root filesystem
400 * whether starting from a local or a network volume.
401 */
402 #define kOSBundleRequiredRoot "Root"
403
404 /*!
405 * @define kOSBundleRequiredLocalRoot
406 * @abstract
407 * This <code>@link kOSBundleRequiredKey OSBundleRequired@/link</code>
408 * value indicates that the kext may be needed to mount the root filesystem
409 * when starting from a local disk.
410 */
411 #define kOSBundleRequiredLocalRoot "Local-Root"
412
413 /*!
414 * @define kOSBundleRequiredNetworkRoot
415 * @abstract
416 * This <code>@link kOSBundleRequiredKey OSBundleRequired@/link</code>
417 * value indicates that the kext may be needed to mount the root filesystem
418 * when starting over a network connection.
419 */
420 #define kOSBundleRequiredNetworkRoot "Network-Root"
421
422 /*!
423 * @define kOSBundleRequiredSafeBoot
424 * @abstract
425 * This <code>@link kOSBundleRequiredKey OSBundleRequired@/link</code>
426 * value indicates that the kext can be loaded during a safe startup.
427 * This value does not normally cause the kext to be read by the booter
428 * or included in startup kext caches.
429 */
430 #define kOSBundleRequiredSafeBoot "Safe Boot"
431
432 /*!
433 * @define kOSBundleRequiredConsole
434 * @abstract
435 * This <code>@link kOSBundleRequiredKey OSBundleRequired@/link</code>
436 * value indicates that the kext may be needed for console access
437 * (specifically in a single-user startup when
438 * <code>@link //apple_ref/doc/man/8/kextd kextd(8)@/link</code>.
439 * does not run)
440 * and should be loaded during early startup.
441 */
442 #define kOSBundleRequiredConsole "Console"
443
444
445 #if PRAGMA_MARK
446 #pragma mark -
447 /********************************************************************/
448 #pragma mark Kext Information
449 /********************************************************************/
450 #endif
451 /*!
452 * @group Kext Information
453 * Types, constants, and macros providing a kext with information
454 * about itself.
455 */
456
457 /*!
458 * @typedef OSKextLoadTag
459 *
460 * @abstract
461 * A unique identifier assigned to a loaded instanace of a kext.
462 *
463 * @discussion
464 * If a kext is unloaded and later reloaded, the new instance
465 * has a different load tag.
466 *
467 * A kext can get its own load tag in the <code>kmod_info_t</code>
468 * structure passed into its module start routine, as the
469 * <code>id</code> field (cast to this type).
470 * You can use the load tag with the functions
471 * <code>@link OSKextRetainKextWithLoadTag
472 * OSKextRetainKextWithLoadTag@/link</code> and
473 * <code>@link OSKextReleaseKextWithLoadTag
474 * OSKextReleaseKextWithLoadTag@/link</code>.
475 */
476 typedef uint32_t OSKextLoadTag;
477
478 /*!
479 * @define kOSKextInvalidLoadTag
480 *
481 * @abstract
482 * A load tag value that will never be used for a loaded kext;
483 * indicates kext not found.
484 */
485 #define kOSKextInvalidLoadTag ((OSKextLoadTag)(-1))
486
487
488 #ifdef KERNEL
489
490 /* Make these visible to kexts only and *not* the kernel.
491 */
492 #if !XNU_KERNEL_PRIVATE
493
494 /*!
495 * @function OSKextGetCurrentLoadTag
496 *
497 * @abstract
498 * Returns the run-time load tag for the calling kext as an
499 * <code>@link OSKextLoadTag OSKextLoadTag@/link</code>.
500 *
501 * @result
502 * The run-time load tag for the calling kext as an
503 * <code>@link OSKextLoadTag@/link</code>.
504 *
505 * @discussion
506 * The load tag identifies this loaded instance of the kext to the kernel
507 * and to kernel functions that operate on kexts.
508 */
509 OSKextLoadTag OSKextGetCurrentLoadTag(void);
510
511 /*!
512 * @function OSKextGetCurrentIdentifier
513 *
514 * @abstract
515 * Returns the CFBundleIdentifier for the calling kext as a C string.
516 *
517 * @result
518 * The CFBundleIdentifier for the calling kext as a C string.
519 */
520 const char * OSKextGetCurrentIdentifier(void);
521
522 /*!
523 * @function OSKextGetCurrentVersionString
524 *
525 * @abstract
526 * Returns the CFBundleVersion for the calling kext as a C string.
527 *
528 * @result
529 * The CFBundleVersion for the calling kext as a C string.
530 */
531 const char * OSKextGetCurrentVersionString(void);
532
533 #endif /* !XNU_KERNEL_PRIVATE */
534
535 #if PRAGMA_MARK
536 #pragma mark -
537 /********************************************************************/
538 #pragma mark Kext Loading C Functions
539 /********************************************************************/
540 #endif
541 /*!
542 * @group Kext Loading C Functions
543 * Functions for loading and tracking kexts in the kernel.
544 */
545
546 /*!
547 * @function OSKextLoadKextWithIdentifier
548 *
549 * @abstract
550 * Request that a kext be loaded.
551 *
552 * @param kextIdentifier The bundle identifier of the kext to be loaded.
553 *
554 * @result
555 * <code>@link //apple_ref/c/macro/kOSReturnSuccess kOSReturnSuccess@/link</code>
556 * if the kext was loaded (or was already loaded).
557 * <code>@link //apple_ref/c/macro/kOSKextReturnDeferred kOSKextReturnDeferred@/link</code>
558 * if the kext was not found and a request
559 * was queued to <code>@link //apple_ref/doc/man/8/kextd kextd(8)@/link</code>.
560 * Other return values indicate a failure to load the kext.
561 *
562 * @discussion
563 * If a kext is already in the kernel but not loaded, it is loaded immediately.
564 * If it isn't found, an asynchronous load request is
565 * made to <code>@link //apple_ref/doc/man/8/kextd kextd(8)@/link</code>
566 * and <code>@link //apple_ref/c/macro/kOSKextReturnDeferred kOSKextReturnDeferred@/link</code> is returned.
567 * There is no general notification or callback mechanism for load requests.
568 */
569 OSReturn OSKextLoadKextWithIdentifier(const char * kextIdentifier);
570
571
572 /*!
573 * @function OSKextRetainKextWithLoadTag
574 *
575 * @abstract
576 * Retain a loaded kext based on its load tag,
577 * and enable autounload for that kext.
578 *
579 * @param loadTag The load tag of the kext to be retained.
580 * See <code>@link OSKextGetCurrentLoadTag@/link</code>.
581 *
582 * @result
583 * <code>@link //apple_ref/c/macro/kOSReturnSuccess kOSReturnSuccess@/link</code>
584 * if the kext was retained.
585 * <code>@link //apple_ref/c/macro/kOSKextReturnNotFound kOSKextReturnNotFound@/link</code>
586 * if the kext was not found.
587 * <code>@link //apple_ref/c/macro/kOSKextReturnInvalidArgument
588 * kOSKextReturnInvalidArgument@/link</code>
589 * if <code>loadTag</code> is
590 * <code>@link kOSKextInvalidLoadTag kOSKextInvalidLoadTag@/link</code>.
591 *
592 * @discussion
593 * Retaining a kext prevents it from being unloaded,
594 * either explicitly or automatically, and enables autounload for the kext.
595 * When autounload is enabled, then shortly after the kext's last reference
596 * is dropped, it will be unloaded if there are no outstanding references to it
597 * and there are no instances of its Libkern C++ subclasses (if any).
598 *
599 * Kexts that define subclasses of
600 * <code>@link //apple_ref/doc/class/IOService IOService@/link</code>
601 * have autounload enabled automatically.
602 * Other kexts can use the reference count to manage automatic unload
603 * without having to define and create Libkern C++ objects.
604 * For example, a filesystem kext can retain itself whenever a new mount
605 * is created, and release itself when a mount is removed.
606 * When the last mount is removed, the kext will be unloaded after a brief delay.
607 *
608 * A kext can get its own load tag using the
609 * <code>@link OSKextGetCurrentLoadTag@/link</code>.
610 *
611 * Kexts should not retain and release other kexts; linkage references
612 * are accounted for internally.
613 */
614 OSReturn OSKextRetainKextWithLoadTag(OSKextLoadTag loadTag);
615
616
617 /*!
618 * @function OSKextReleaseKextWithLoadTag
619 *
620 * @abstract
621 * Release a loaded kext based on its load tag.
622 *
623 * @param loadTag The load tag of the kext to be released.
624 * See <code>@link OSKextGetCurrentLoadTag@/link</code>.
625 *
626 * @result
627 * <code>@link //apple_ref/c/macro/kOSReturnSuccess kOSReturnSuccess@/link</code>
628 * if the kext was released.
629 * <code>@link //apple_ref/c/macro/kOSKextReturnNotFound
630 * kOSKextReturnNotFound@/link</code>
631 * if the kext was not found.
632 * <code>@link //apple_ref/c/macro/kOSKextReturnInvalidArgument
633 * kOSKextReturnInvalidArgument@/link</code>
634 * if <code>loadTag</code> is
635 * <code>@link kOSKextInvalidLoadTag kOSKextInvalidLoadTag@/link</code>.
636 *
637 * @discussion
638 * The kext should have been retained previously via
639 * <code>@link OSKextRetainKextWithLoadTag@/link</code>.
640 *
641 * This function schedules an autounload scan for all kexts.
642 * When that scan occurs, if a kext has autounload enabled,
643 * it will be unloaded if there are no outstanding references to it
644 * and there are no instances of its Libkern C++ classes (if any).
645 *
646 * Kexts that define subclasses of
647 * <code>@link //apple_ref/doc/class/IOService IOService@/link</code>
648 * have autounload enabled automatically.
649 * Other kexts can use the reference count to manage automatic unload
650 * without having to define and create Libkern C++ objects.
651 * For example, a filesystem kext can be retained whenever a new mount
652 * is created, and released when a mount is removed.
653 * When the last mount is removed, the kext will be unloaded after a brief delay.
654 *
655 * While the autounload scan takes place after a delay of at least a minute,
656 * a kext that manages its own reference counts for autounload should
657 * be prepared to have its module stop function called even while the function
658 * calling this function is still running.
659 *
660 * A kext can get its own load tag using the
661 * <code>@link OSKextGetCurrentLoadTag@/link</code>.
662 *
663 * Kexts should not retain and release other kexts; linkage references
664 * are accounted for internally.
665 */
666 OSReturn OSKextReleaseKextWithLoadTag(OSKextLoadTag loadTag);
667
668 #if PRAGMA_MARK
669 /********************************************************************/
670 #pragma mark -
671 #pragma mark Kext Requests
672 /********************************************************************/
673 #endif
674 /*!
675 * @group Kext Requests to User Space
676 * Functions for making requests to kextd in user space.
677 */
678
679 /*!
680 * @typedef OSKextRequestTag
681 *
682 * @abstract
683 * Identifies a kext request made to user space.
684 */
685 typedef uint32_t OSKextRequestTag;
686
687 /*!
688 * @define kOSKextRequestTagInvalid
689 *
690 * @abstract
691 * A request tag value that will never be used for a kext request;
692 * indicates failure to create/queue the request.
693 */
694 #define kOSKextRequestTagInvalid ((OSKextRequestTag)-1)
695
696 /*!
697 * @typedef OSKextRequestResourceCallback
698 *
699 * @abstract
700 * Invoked to provide results for a kext resource request.
701 *
702 * @param requestTag The tag of the request that the callback pertains to.
703 * @param result The result of the request:
704 * <code>@link kOSReturnSuccess
705 * kOSReturnSuccess@/link</code>
706 * if the request was fulfilled;
707 * <code>@link kOSKextReturnTimeout
708 * kOSKextReturnTimeout@/link</code>
709 * if the request has timed out;
710 * <code>@link kOSKextReturnStopping
711 * kOSKextReturnStopping@/link</code>
712 * if the kext containing the callback
713 * address for the kext is being unloaded;
714 * or other values on error.
715 * @param resourceData A pointer to the requested resource data.
716 * Owned by the system; the kext should make a copy
717 * if it needs to keep the data past the callback.
718 * @param resourceDataLength The length of <code>resourceData</code>.
719 * @param context The context pointer originally passed to
720 * <code>@link OSKextRequestResource
721 * OSKextRequestResource@/link</code>.
722 */
723 typedef void (* OSKextRequestResourceCallback)(
724 OSKextRequestTag requestTag,
725 OSReturn result,
726 const void * resourceData,
727 uint32_t resourceDataLength,
728 void * context);
729
730 /*!
731 * @function OSKextRequestResource
732 *
733 * @abstract
734 * Requests data from a nonlocalized resource file in a kext bundle on disk.
735 *
736 * @param kextIdentifier The CFBundleIdentifier of the kext
737 * from which to read the file.
738 * @param resourceName The name of the resource file to read.
739 * @param callback A pointer to a callback function; the address
740 * must be within a currently-loaded kext.
741 * @param context A pointer to arbitrary run-time data
742 * that will be passed to the callback
743 * when it is invoked. May be <code>NULL</code>.
744 * @param requestTagOut If non-<code>NULL</code>,
745 * filled on success with a tag identifying the
746 * pending request
747 * (or on failure with <code>@link kOSKextRequestTagInvalid
748 * kOSKextRequestTagInvalid@/link</code>;
749 * can be used with
750 * <code>@link OSKextCancelRequest
751 * OSKextCancelRequest@/link</code>.
752 *
753 * @result
754 * <code>@link kOSReturnSuccess kOSReturnSuccess@/link</code>
755 * if the request is successfully queued.
756 * <code>@link kOSKextReturnInvalidArgument kOSKextReturnInvalidArgument@/link</code>
757 * if <code>kextIdentifier</code> or <code>resourceName</code> or if
758 * <code>callback</code> is not an address within a loaded kext executable.
759 * <code>@link kOSKextReturnStopping kOSKextReturnStopping@/link</code>
760 * if an unload attempt is being made
761 * on the kext containing <code>callback</code>.
762 * Other <code>OSKextReturn...</code> errors are possible.
763 *
764 * @discussion
765 * This function queues an asynchronous request to the user-space kext daemon
766 * <code>@link //apple_ref/doc/man/8/kextd kextd(8)@/link</code>;
767 * requests for resources early in system startup
768 * will not be fulfilled until that daemon starts.
769 * Requests made by a kext while that kext is loading
770 * (specifically in the kext's module start routine)
771 * will not be fulfilled until after the start routine returns and
772 * the kext is completely loaded.
773 * Kexts requesting resources should be sure to perform appropriate locking
774 * in the callback function.
775 *
776 * Kext resources are stored in the kext's on-disk bundle under the
777 * Resources subdirectory.
778 * See {@linkdoc //apple_ref/doc/uid/10000123i Bundle Programming Guide}
779 * for an overview of bundle structure.
780 * The localization context of the kext daemon
781 * (namely that of the superuser)
782 * will be used in retrieving resources;
783 * kext resources intended for use in the kernel
784 * should generally not be localized.
785 *
786 * <code>callback</code> is guaranteed to be invoked except when:
787 * <ul>
788 * <li>@link OSKextCancelRequest <code>OSKextCancelRequest</code>@/link
789 * is used to cancel the request.
790 * In this case the kext gets the <code>context</code> pointer
791 * and can clean it up.</li>
792 * <li>The request is made during a kext's module start routine
793 * and the start routine returns an error.
794 * In this case, callbacks cannot be safely invoked, so
795 * the kext should clean up all request contexts
796 * when returning the error from the start routine.</li>
797 * </ul>
798 *
799 * Kexts with pending requests are not subject to autounload,
800 * but requests are subject to timeout after a few minutes.
801 * If that amount of time passes with no response from user space,
802 * <code>callback</code> is invoked with a result of.
803 * <code>@link kOSKextReturnTimeout kOSKextReturnTimeout@/link</code>.
804 *
805 * Kexts that are explicitly unloaded have all pending request callbacks
806 * invoked with a result of
807 * <code>@link kOSKextReturnStopping kOSKextReturnStopping@/link</code>.
808 * The kext must handle these callbacks,
809 * even if its stop routine will prevent unloading.
810 * If the kext does prevent unloading, it can reissue resource requests
811 * outside of the stop function.
812 */
813 OSReturn OSKextRequestResource(
814 const char * kextIdentifier,
815 const char * resourceName,
816 OSKextRequestResourceCallback callback,
817 void * context,
818 OSKextRequestTag * requestTagOut);
819
820 /*!
821 * @function OSKextCancelRequest
822 *
823 * @abstract
824 * Cancels a pending user-space kext request without invoking the callback.
825 *
826 * @param requestTag A tag identifying a pending request.
827 * @param contextOut If non-<code>NULL</code>, filled with the context pointer
828 * originally passed with the request.
829 *
830 * @result
831 * <code>@link kOSReturnSuccess kOSReturnSuccess@/link</code>
832 * if the request is successfully canceled.
833 * <code>@link kOSKextReturnNotFound kOSKextReturnNotFound@/link</code>
834 * if <code>requestTag</code> does not identify any pending request.
835 * Other <code>OSKextReturn...</code> errors are possible.
836 *
837 * @discussion
838 * This function cancels a pending request if it exists,
839 * so that its callback will not be invoked.
840 * It returns in <code>contextOut</code>
841 * the context pointer used to create the request
842 * so that any resources allocated for the request can be cleaned up.
843 *
844 * Kexts do not need to cancel outstanding requests
845 * in their module stop functions;
846 * when a kext is unloaded, all pending request callbacks
847 * are invoked with a result of
848 * <code>@link kOSKextReturnTimeout kOSKextReturnTimeout@/link</code>
849 * before the stop function is called.
850 */
851 OSReturn OSKextCancelRequest(
852 OSKextRequestTag requestTag,
853 void ** contextOut);
854
855
856 #if PRAGMA_MARK
857 #pragma mark -
858 /********************************************************************/
859 #pragma mark Weak linking
860 /********************************************************************/
861 #endif
862 /*!
863 * @group Weak Linking
864 * Support for weak references to symbols in kexts.
865 */
866
867 /*!
868 * @var gOSKextUnresolved
869 *
870 * @abstract
871 * The value to which a kext's unresolved, weakly-referenced symbols are bound.
872 *
873 * @discussion
874 * A kext must test a weak symbol before using it. A weak symbol
875 * is only safe to use if it is not equal to <code>gOSKextUnresolved</code>.
876 *
877 * Example for a weak symbol named <code>foo</code>:
878 * <pre>
879 * @textblock
880 * if (&foo != gOSKextUnresolved) {
881 * foo();
882 * } else {
883 * printf("foo() is not supported\n");
884 * }
885 * @/textblock
886 * </pre>
887 */
888 extern const void * gOSKextUnresolved;
889
890 /*!
891 * @define OSKextSymbolIsResolved
892 *
893 * @abstract
894 * Checks whether a weakly-referenced symbol has been resolved.
895 *
896 * @param weak_sym The weak symbol to be tested for resolution.
897 *
898 * @result
899 * <code>TRUE</code> if weak_sym is resolved, or <code>FALSE</code>
900 * if weak_sym is unresolved.
901 *
902 * @discussion
903 * This is a convenience macro for testing if weak symbols are resolved.
904 *
905 * Example for a weak symbol named <code>foo</code>:
906 * <pre>
907 * @textblock
908 * if (OSKextSymbolIsResolved(foo)) {
909 * foo();
910 * } else {
911 * printf("foo() is not resolved\n");
912 * }
913 * @/textblock
914 * </pre>
915 */
916 #define OSKextSymbolIsResolved(weak_sym) \
917 (&(weak_sym) != gOSKextUnresolved)
918
919 #endif /* KERNEL */
920
921 __END_DECLS
922
923 #endif /* _LIBKERN_OSKEXTLIB_H */