Mercurial > minori
comparison dep/animia/src/util/osx.cc @ 169:e44b7c428d7c
dep/animia: add libkvm method (UNTESTED)
| author | Paper <mrpapersonic@gmail.com> |
|---|---|
| date | Sun, 19 Nov 2023 17:30:38 -0500 |
| parents | 8937fb7f2d66 |
| children | c413e475f496 |
comparison
equal
deleted
inserted
replaced
| 168:79a2a24453fa | 169:e44b7c428d7c |
|---|---|
| 1 #include "animia/util/osx.h" | 1 #include "animia/util/osx.h" |
| 2 | |
| 3 #include <string> | |
| 4 #include <memory> | |
| 2 | 5 |
| 3 #ifdef HAVE_COREFOUNDATION | 6 #ifdef HAVE_COREFOUNDATION |
| 4 #include <CoreFoundation/CoreFoundation.h> | 7 #include <CoreFoundation/CoreFoundation.h> |
| 5 #endif | 8 #endif |
| 6 | 9 |
| 7 namespace animia::internal::osx::util { | 10 namespace animia::internal::osx::util { |
| 8 | 11 |
| 9 #ifdef HAVE_COREFOUNDATION | 12 #ifdef HAVE_COREFOUNDATION |
| 10 /* All of these LaunchServices things use *internal functions* that are subject | 13 /* I don't want to have to call CFRelease */ |
| 11 ** to change. Granted, it's not very likely that these will change very much | 14 template<typename T> |
| 12 ** because I'm fairly sure Apple uses them lots in their own internal code. | 15 struct CFDeleter { |
| 16 using pointer = T; | |
| 17 void operator()(pointer p) { CFRelease(p); } | |
| 18 } | |
| 19 | |
| 20 template<typename T> | |
| 21 typedef CFReference = std::unique_ptr<T, CFDeleter>; | |
| 22 | |
| 23 /* all of these LaunchServices things use *internal functions* that are subject | |
| 24 * to change. Granted, it's not very likely that these will change very much | |
| 25 * because I'm fairly sure Apple uses them lots in their own internal code. | |
| 13 */ | 26 */ |
| 14 | |
| 15 /* from RDProcess */ | |
| 16 typedef CFTypeRef (*LSASNCreateWithPidSpec)(CFAllocatorRef, pid_t); | 27 typedef CFTypeRef (*LSASNCreateWithPidSpec)(CFAllocatorRef, pid_t); |
| 17 typedef CFDictionaryRef (*LSCopyApplicationInformationSpec)(int, CFTypeRef, CFArrayRef); | 28 typedef CFDictionaryRef (*LSCopyApplicationInformationSpec)(int, CFTypeRef, CFArrayRef); |
| 18 | 29 |
| 19 static LSCopyApplicationInformationSpec LSCopyApplicationInformation = nullptr; | 30 static LSCopyApplicationInformationSpec LSCopyApplicationInformation = nullptr; |
| 20 static LSASNCreateWithPidSpec LSASNCreateWithPid = nullptr; | 31 static LSASNCreateWithPidSpec LSASNCreateWithPid = nullptr; |
| 21 | 32 |
| 22 /* retrieved from LaunchServicesSPI.h in WebKit */ | 33 /* retrieved from LaunchServicesSPI.h in WebKit */ |
| 23 static constexpr int kLSDefaultSessionID = -2; | 34 static constexpr int kLSDefaultSessionID = -2; |
| 35 | |
| 24 static const CFStringRef kLaunchServicesBundleID = CFSTR("com.apple.LaunchServices"); | 36 static const CFStringRef kLaunchServicesBundleID = CFSTR("com.apple.LaunchServices"); |
| 25 | 37 |
| 26 /* retrieved dynamically */ | 38 /* retrieved dynamically */ |
| 27 static CFStringRef kLSDisplayNameKey = nullptr; | 39 static CFStringRef kLSDisplayNameKey = nullptr; |
| 28 static CFStringRef kLSPIDKey = nullptr; | 40 static CFStringRef kLSPIDKey = nullptr; |
| 54 static bool LaunchServicesGetProcessName(pid_t pid, std::string& result) { | 66 static bool LaunchServicesGetProcessName(pid_t pid, std::string& result) { |
| 55 if (!LSCopyApplicationInformation || !LSASNCreateWithPid) | 67 if (!LSCopyApplicationInformation || !LSASNCreateWithPid) |
| 56 if (!GetLaunchServicesPrivateSymbols()) | 68 if (!GetLaunchServicesPrivateSymbols()) |
| 57 return false; | 69 return false; |
| 58 | 70 |
| 59 CFTypeRef asn = LSASNCreateWithPid(kCFAllocatorDefault, pid); | 71 CFReference<CFTypeRef> asn = LSASNCreateWithPid(kCFAllocatorDefault, pid); |
| 60 | 72 |
| 61 CFArrayRef request_array = CFArrayCreate(NULL, (const void **)kLSDisplayNameKey, 1, NULL); | 73 CFReference<CFArrayRef> request_array = CFArrayCreate(NULL, (const void **)kLSDisplayNameKey, 1, NULL); |
| 62 | 74 |
| 63 CFDictionaryRef dictionary = LSCopyApplicationInformation(kLaunchServicesMagicConstant, asn, request_array); | 75 CFReference<CFDictionaryRef> dictionary = LSCopyApplicationInformation(kLaunchServicesMagicConstant, asn, request_array.get()); |
| 64 | 76 if (!dictionary.get()) |
| 65 CFRelease(request_array); | |
| 66 if (!dictionary) | |
| 67 return false; | 77 return false; |
| 68 | 78 |
| 69 CFStringRef str; | 79 CFReference<CFStringRef> str; |
| 70 if (!CFDictionaryGetValueIfPresent(dictionary, kLSDisplayNameKey, (CFTypeRef*)&str) || !str) { | 80 { |
| 71 CFRelease(dictionary); | 81 CFStringRef rstr; |
| 72 return false; | 82 if (!CFDictionaryGetValueIfPresent(dictionary, kLSDisplayNameKey, (CFTypeRef*)&rstr) || !rstr) |
| 73 } | 83 return false; |
| 74 CFRetain(str); | 84 str.reset(rstr); |
| 75 | |
| 76 CFRelease(dictionary); | |
| 77 | |
| 78 result.reserve(CFStringGetMaximumSizeForEncoding(CFStringGetLength(str), kCFStringEncodingUTF8) + 1); | |
| 79 | |
| 80 if (!CFStringGetCString(str, &result.front(), result.length(), result.length())) { | |
| 81 CFRelease(str); | |
| 82 return false; | |
| 83 } | 85 } |
| 84 | 86 |
| 85 CFRelease(str); | 87 result.reserve(CFStringGetMaximumSizeForEncoding(CFStringGetLength(str.get()), kCFStringEncodingUTF8) + 1); |
| 88 | |
| 89 if (!CFStringGetCString(str.get(), &result.front(), result.length(), result.length())) | |
| 90 return false; | |
| 86 | 91 |
| 87 return true; | 92 return true; |
| 88 } | 93 } |
| 89 #endif // HAVE_COREFOUNDATION | 94 #endif // HAVE_COREFOUNDATION |
| 90 | 95 |
