1 /*
2 * Copyright (c) 2022-2024 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 #include <sys/vnode.h>
30 extern "C" {
31 #include <vfs/vfs_exclave_fs.h>
32 }
33 #include <IOKit/IOPlatformExpert.h>
34
35 #define APFS_VOLUME_OBJECT "AppleAPFSVolume"
36 #define kAPFSVolGroupUUIDKey "VolGroupUUID"
37
38 extern "C"
39 int
vfs_exclave_fs_query_volume_group(const uuid_string_t vguuid_str,bool * exists)40 vfs_exclave_fs_query_volume_group(const uuid_string_t vguuid_str, bool *exists)
41 {
42 #if XNU_TARGET_OS_OSX
43 OSDictionary *target = NULL, *filter = NULL;
44 OSString *string = NULL;
45 IOService *service = NULL;
46 int error = 0;
47 uuid_t vguuid;
48
49 *exists = false;
50
51 // Verify input uuid is a valid uuid
52 error = uuid_parse(vguuid_str, vguuid);
53 if (error) {
54 return EINVAL;
55 }
56
57 // Look for APFS volume object that has Volume Group that matches the one we're looking for
58 target = IOService::serviceMatching(APFS_VOLUME_OBJECT);
59 if (!target) {
60 // No APFS volumes found?
61 return ENXIO;
62 }
63
64 filter = OSDictionary::withCapacity(1);
65 if (!filter) {
66 error = ENOMEM;
67 goto out;
68 }
69
70 string = OSString::withCStringNoCopy(vguuid_str);
71 if (!string) {
72 error = ENOMEM;
73 goto out;
74 }
75
76 if (!filter->setObject(kAPFSVolGroupUUIDKey, string)) {
77 error = ENXIO;
78 goto out;
79 }
80
81 if (!target->setObject(gIOPropertyMatchKey, filter)) {
82 error = ENXIO;
83 goto out;
84 }
85
86 if ((service = IOService::copyMatchingService(target)) != NULL) {
87 *exists = true;
88 }
89
90 out:
91 if (target) {
92 target->release();
93 }
94
95 if (filter) {
96 filter->release();
97 }
98
99 if (string) {
100 string->release();
101 }
102
103 if (service) {
104 service->release();
105 }
106
107 return error;
108 #else
109 #pragma unused(vguuid_str)
110 #pragma unused(exists)
111 return ENOTSUP;
112 #endif
113 }
114