comparison dep/animia/src/util/osx.cc @ 162:61b76c7b656a

dep/animia: add os x launchservices method
author Paper <mrpapersonic@gmail.com>
date Fri, 17 Nov 2023 16:49:57 -0500
parents
children 44c5e6dd9488
comparison
equal deleted inserted replaced
161:71752dcbb49f 162:61b76c7b656a
1 /* A wrapper around multiple LaunchServices things */
2
3 #include "animia/util/osx.h"
4
5 #include <CoreFoundation/CoreFoundation.h>
6
7 #include <iostream>
8
9 namespace animia::internal::osx::util {
10
11 #define RDSymbolNameStr(symbol) (CFSTR("_"#symbol))
12
13 static constexpr int kLaunchServicesMagicConstant = -2; // or -1, dunno the difference
14
15 typedef CFTypeRef (*LSASNCreateWithPidSpec)(CFAllocatorRef, pid_t);
16 typedef CFDictionaryRef (*LSCopyApplicationInformationSpec)(int, CFTypeRef, CFArrayRef);
17
18 static LSCopyApplicationInformationSpec LSCopyApplicationInformation = nullptr;
19 static LSASNCreateWithPidSpec LSASNCreateWithPid = nullptr;
20
21 static CFStringRef (kLSDisplayNameKey) = nullptr;
22 static CFStringRef (kLSPIDKey) = nullptr;
23
24 static CFStringRef (kLaunchServicesBundleID) = CFSTR("com.apple.LaunchServices");
25
26 static bool FindLaunchServicesPrivateSymbols() {
27 CFBundleRef launch_services_bundle = CFBundleGetBundleWithIdentifier(kLaunchServicesBundleID);
28 if (!launch_services_bundle)
29 return false;
30
31 LSCopyApplicationInformation = (LSCopyApplicationInformationSpec)CFBundleGetFunctionPointerForName(launch_services_bundle, RDSymbolNameStr(LSCopyApplicationInformation));
32 if (!LSCopyApplicationInformation)
33 return false;
34
35 LSASNCreateWithPid = (LSASNCreateWithPidSpec)CFBundleGetFunctionPointerForName(launch_services_bundle, RDSymbolNameStr(LSASNCreateWithPid));
36 if (!LSASNCreateWithPid)
37 return false;
38
39 kLSDisplayNameKey = *(CFStringRef*)CFBundleGetDataPointerForName(launch_services_bundle, RDSymbolNameStr(kLSDisplayNameKey));
40 if (!kLSDisplayNameKey)
41 return false;
42
43 kLSPIDKey = *(CFStringRef*)CFBundleGetDataPointerForName(launch_services_bundle, RDSymbolNameStr(kLSPIDKey));
44 if (!kLSPIDKey)
45 return false;
46
47 return true;
48 }
49
50 bool LaunchServicesGetProcessName(pid_t pid, std::string& result) {
51 if (!LSCopyApplicationInformation || !LSASNCreateWithPid)
52 if (!FindLaunchServicesPrivateSymbols())
53 return false;
54
55 CFTypeRef asn = LSASNCreateWithPid(kCFAllocatorDefault, pid);
56
57 CFArrayRef request_array = CFArrayCreate(NULL, (const void **)kLSDisplayNameKey, 1, NULL);
58
59 CFDictionaryRef dictionary = LSCopyApplicationInformation(kLaunchServicesMagicConstant, asn, request_array);
60
61 CFRelease(request_array);
62 if (!dictionary)
63 return false;
64
65 CFStringRef str;
66 if (!CFDictionaryGetValueIfPresent(dictionary, kLSDisplayNameKey, (CFTypeRef*)&str) || !str) {
67 CFRelease(dictionary);
68 return false;
69 }
70 CFRetain(str);
71
72 CFRelease(dictionary);
73
74 result.reserve(CFStringGetMaximumSizeForEncoding(CFStringGetLength(str), kCFStringEncodingUTF8) + 1);
75
76 if (!CFStringGetCString(str, &result.front(), result.length(), result.length())) {
77 CFRelease(str);
78 return false;
79 }
80
81 CFRelease(str);
82
83 return true;
84 }
85
86 }