Skip to content

Commit 1cc6658

Browse files
committed
Updated accessibility checks to use dlopen by default and avoid all the warnings and weak-linking headaches.
1 parent c8cbec5 commit 1cc6658

File tree

1 file changed

+65
-3
lines changed

1 file changed

+65
-3
lines changed

darwin/hook_thread.c

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@
1919
#include <config.h>
2020
#endif
2121

22+
// FIXME Move to osx_input_helper.h after testing.
23+
#ifndef USE_WEAK_IMPORT
24+
#include <dlfcn.h>
25+
#endif
26+
2227
#include <ApplicationServices/ApplicationServices.h>
2328
#include <pthread.h>
2429
#include <stdbool.h>
@@ -38,19 +43,27 @@ pthread_mutex_t hook_control_mutex = PTHREAD_MUTEX_INITIALIZER;
3843
static pthread_t hook_thread_id; // TODO = 0; ?
3944
static pthread_attr_t hook_thread_attr;
4045

41-
// Required to dynamically check for AXIsProcessTrustedWithOptions availability.
4246
// FIXME Move to osx_input_helper.h after testing.
47+
#ifdef USE_WEAK_IMPORT
48+
// Required to dynamically check for AXIsProcessTrustedWithOptions availability.
4349
extern Boolean AXIsProcessTrustedWithOptions(CFDictionaryRef options) __attribute__((weak_import));
4450
extern CFStringRef kAXTrustedCheckOptionPrompt __attribute__((weak_import));
51+
#else
52+
typedef Boolean (*AXIsProcessTrustedWithOptions_t)(CFDictionaryRef options);
53+
typedef Boolean (*AXAPIEnabled_t)(void);
54+
#endif
4555

4656
static void *hook_thread_proc(void *arg) {
4757
int *status = (int *) arg;
4858
*status = UIOHOOK_FAILURE;
4959

5060
bool accessibilityEnabled = false;
61+
62+
// FIXME Move to osx_input_helper.h after testing.
63+
#ifdef USE_WEAK_IMPORT
5164
// Check and make sure assistive devices is enabled.
5265
if (AXIsProcessTrustedWithOptions != NULL) {
53-
// 10.9 and later
66+
// New accessibility API 10.9 and later.
5467
const void * keys[] = { kAXTrustedCheckOptionPrompt };
5568
const void * values[] = { kCFBooleanTrue };
5669

@@ -65,9 +78,58 @@ static void *hook_thread_proc(void *arg) {
6578
accessibilityEnabled = AXIsProcessTrustedWithOptions(options);
6679
}
6780
else {
68-
// 10.8 and older
81+
// Old accessibility check 10.8 and older.
6982
accessibilityEnabled = AXAPIEnabled();
7083
}
84+
#else
85+
const char *dlError = NULL;
86+
void *libApplicaitonServices = dlopen("/System/Library/Frameworks/ApplicationServices.framework/ApplicationServices", RTLD_LAZY);
87+
dlError = dlerror();
88+
if (libApplicaitonServices != NULL && dlError == NULL) {
89+
// Check for the new function AXIsProcessTrustedWithOptions().
90+
AXIsProcessTrustedWithOptions_t fpAXIsProcessTrustedWithOptions = (AXIsProcessTrustedWithOptions_t) dlsym(libApplicaitonServices, "AXIsProcessTrustedWithOptions");
91+
dlError = dlerror();
92+
if (fpAXIsProcessTrustedWithOptions != NULL && dlError == NULL) {
93+
// New accessibility API 10.9 and later.
94+
const void * keys[] = { kAXTrustedCheckOptionPrompt };
95+
const void * values[] = { kCFBooleanTrue };
96+
97+
CFDictionaryRef options = CFDictionaryCreate(
98+
kCFAllocatorDefault,
99+
keys,
100+
values,
101+
sizeof(keys) / sizeof(*keys),
102+
&kCFCopyStringDictionaryKeyCallBacks,
103+
&kCFTypeDictionaryValueCallBacks);
104+
105+
accessibilityEnabled = (*fpAXIsProcessTrustedWithOptions)(options);
106+
}
107+
else {
108+
logger(LOG_LEVEL_DEBUG, "%s [%u]: Failed to locate AXIsProcessTrustedWithOptions(). (%s)\n",
109+
__FUNCTION__, __LINE__, dlError);
110+
111+
// Check for the fallback function AXAPIEnabled().
112+
AXAPIEnabled_t fpAXAPIEnabled = (AXAPIEnabled_t) dlsym(libApplicaitonServices, "AXAPIEnabled");
113+
dlError = dlerror();
114+
if (fpAXAPIEnabled != NULL && dlError == NULL) {
115+
// Old accessibility check 10.8 and older.
116+
accessibilityEnabled = (*fpAXAPIEnabled)();
117+
}
118+
else {
119+
// Could not load the AXAPIEnabled function!
120+
logger(LOG_LEVEL_ERROR, "%s [%u]: Failed to locate AXAPIEnabled()! (%s)\n",
121+
__FUNCTION__, __LINE__, dlError);
122+
}
123+
}
124+
125+
dlclose(libApplicaitonServices);
126+
}
127+
else {
128+
// Could not load the ApplicationServices framework!
129+
logger(LOG_LEVEL_ERROR, "%s [%u]: Failed to lazy load the ApplicationServices framework! (%s)\n",
130+
__FUNCTION__, __LINE__, dlError);
131+
}
132+
#endif
71133

72134
if (accessibilityEnabled == true) {
73135
logger(LOG_LEVEL_DEBUG, "%s [%u]: Accessibility API is enabled.\n",

0 commit comments

Comments
 (0)