mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-26 02:49:02 -04:00
Fixed a crash on macOS when filesystem doesn't report UUID
Some checks failed
Some checks failed
This commit is contained in:
parent
ad2a36f2c7
commit
f64d582960
2 changed files with 71 additions and 26 deletions
1
HISTORY
1
HISTORY
|
|
@ -3,6 +3,7 @@ SnapRAID HISTORY
|
|||
|
||||
13.1 WIP
|
||||
========
|
||||
* Fixed a crash on macOS when filesystem doesn't report UUID
|
||||
* Added support for local exclusion rules via .snapraidignore files placed
|
||||
directly within the array directory tree. This allows for granular,
|
||||
directory-level control over which files and folders are excluded from
|
||||
|
|
|
|||
|
|
@ -599,38 +599,82 @@ static int devuuid_blkid(uint64_t device, char* uuid, size_t uuid_size)
|
|||
#ifdef __APPLE__
|
||||
static int devuuid_darwin(const char* path, char* uuid, size_t uuid_size)
|
||||
{
|
||||
CFStringRef path_apple = CFStringCreateWithCString(kCFAllocatorDefault, path, kCFStringEncodingUTF8);
|
||||
DASessionRef session = DASessionCreate(kCFAllocatorDefault);
|
||||
CFStringRef path_apple = 0;
|
||||
DASessionRef session = 0;
|
||||
CFURLRef path_appler = 0;
|
||||
int result = -1;
|
||||
|
||||
CFURLRef path_appler = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, path_apple, kCFURLPOSIXPathStyle, false);
|
||||
DADiskRef disk;
|
||||
do {
|
||||
*uuid = 0;
|
||||
|
||||
path_apple = CFStringCreateWithCString(kCFAllocatorDefault, path, kCFStringEncodingUTF8);
|
||||
if (!path_apple)
|
||||
goto bail;
|
||||
|
||||
session = DASessionCreate(kCFAllocatorDefault);
|
||||
if (!session)
|
||||
goto bail;
|
||||
|
||||
path_appler = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, path_apple, kCFURLPOSIXPathStyle, false);
|
||||
if (!path_appler)
|
||||
goto bail;
|
||||
|
||||
/* find the mount point */
|
||||
DADiskRef disk = NULL;
|
||||
while (path_appler) {
|
||||
disk = DADiskCreateFromVolumePath(kCFAllocatorDefault, session, path_appler);
|
||||
if (disk) {
|
||||
CFRelease(path_appler);
|
||||
if (disk)
|
||||
break;
|
||||
|
||||
CFURLRef parent = CFURLCreateCopyDeletingLastPathComponent(kCFAllocatorDefault, path_appler);
|
||||
if (!parent)
|
||||
break;
|
||||
|
||||
/* check if we hit the root (parent == child) */
|
||||
if (CFEqual(parent, path_appler)) {
|
||||
CFRelease(parent);
|
||||
break;
|
||||
} else {
|
||||
CFURLRef parent_path_appler = CFURLCreateCopyDeletingLastPathComponent(kCFAllocatorDefault, path_appler);
|
||||
CFRelease(path_appler);
|
||||
path_appler = parent_path_appler;
|
||||
}
|
||||
} while (true); // This is guaranteed to succeed eventually because it'll hit `/`.
|
||||
|
||||
CFDictionaryRef description = DADiskCopyDescription(disk);
|
||||
CFUUIDRef uuid_apple = CFDictionaryGetValue(description, kDADiskDescriptionVolumeUUIDKey);
|
||||
CFStringRef uuid_string = CFUUIDCreateString(kCFAllocatorDefault, uuid_apple);
|
||||
bool success = CFStringGetCString(uuid_string, uuid, uuid_size, kCFStringEncodingUTF8);
|
||||
CFRelease(uuid_string);
|
||||
CFRelease(description);
|
||||
CFRelease(disk);
|
||||
CFRelease(session);
|
||||
CFRelease(path_apple);
|
||||
|
||||
if (success) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
CFRelease(path_appler);
|
||||
path_appler = parent;
|
||||
}
|
||||
|
||||
/* safely extract the UUID */
|
||||
if (disk) {
|
||||
CFDictionaryRef description = DADiskCopyDescription(disk);
|
||||
if (description) {
|
||||
/* key might not exist for NTFS/ExFAT on some drivers */
|
||||
const void* value = (CFUUIDRef)CFDictionaryGetValue(description, kDADiskDescriptionVolumeUUIDKey);
|
||||
CFStringRef uuid_string = NULL;
|
||||
|
||||
if (value) {
|
||||
if (CFGetTypeID(value) == CFUUIDGetTypeID()) {
|
||||
uuid_string = CFUUIDCreateString(kCFAllocatorDefault, (CFUUIDRef)value);
|
||||
} else if (CFGetTypeID(value) == CFStringGetTypeID()) {
|
||||
/* if it's already a string, retain it so we can release it later consistently */
|
||||
uuid_string = (CFStringRef)CFRetain(value);
|
||||
}
|
||||
}
|
||||
|
||||
if (uuid_string) {
|
||||
if (CFStringGetCString(uuid_string, uuid, uuid_size, kCFStringEncodingUTF8)) {
|
||||
result = 0; /* success */
|
||||
}
|
||||
CFRelease(uuid_string);
|
||||
}
|
||||
|
||||
CFRelease(description);
|
||||
}
|
||||
CFRelease(disk);
|
||||
}
|
||||
|
||||
bail:
|
||||
/* clean up */
|
||||
if (path_appler) CFRelease(path_appler);
|
||||
if (session) CFRelease(session);
|
||||
if (path_apple) CFRelease(path_apple);
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue