forked from Lessica/RocketBootstrap-Example
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTweak.x
More file actions
153 lines (124 loc) · 4.74 KB
/
Copy pathTweak.x
File metadata and controls
153 lines (124 loc) · 4.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#import <stdio.h>
#import <notify.h>
#import <Foundation/Foundation.h>
#import <rocketbootstrap/rocketbootstrap.h>
static CFMessagePortRef _serverPort = nil;
static CFDataRef _arguments = nil;
static CFDataRef _response = nil;
static CFDataRef ServerCallback(
CFMessagePortRef port,
SInt32 messageID,
CFDataRef data,
void *info
) {
// client put arguments
if (messageID == 0x1111) {
if (_arguments) {
CFRelease(_arguments);
_arguments = nil;
}
_arguments = CFDataCreateCopy(kCFAllocatorDefault, data);
notify_post("com.darwindev.savt.notify.client_put_arguments");
return nil;
}
// executor get arguments
else if (messageID == 0x1112) {
if (!_arguments)
return nil;
CFDataRef arguments = CFDataCreateCopy(kCFAllocatorDefault, _arguments);
CFRelease(_arguments);
_arguments = nil;
return arguments; // released by system
}
// executor put response
else if (messageID == 0x1113) {
if (_response) {
CFRelease(_response);
_response = nil;
}
_response = CFDataCreateCopy(kCFAllocatorDefault, data);
notify_post("com.darwindev.savt.notify.executor_put_response");
return nil;
}
// client get response
else if (messageID == 0x1114) {
if (!_response)
return nil;
CFDataRef response = CFDataCreateCopy(kCFAllocatorDefault, _response);
CFRelease(_response);
_response = nil;
return response; // released by system
}
return nil;
}
// executor
static void ClientDidPutArguments(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo)
{
// get arguments from server
CFDataRef respData = NULL;
SInt32 reqStatus =
CFMessagePortSendRequest(
_serverPort,
0x1112 /* executor get arguments */,
NULL /* no request data */,
1.0 /* send timeout */,
1.0 /* recv timeout */,
kCFRunLoopDefaultMode /* indicate a two-way message */,
&respData /* response data */
);
if (reqStatus == kCFMessagePortSuccess) {
NSDictionary *argumentDict = [NSPropertyListSerialization propertyListWithData:CFBridgingRelease(respData) options:kNilOptions format:nil error:nil];
NSDictionary *resultDict = nil;
// do main stuff in executor
resultDict = @{@"reply": [NSString stringWithFormat: @"Hello %@, I am %@.", argumentDict[@"name"], [[NSBundle mainBundle] bundleIdentifier]]};
CFDataRef resultData = (CFDataRef)CFBridgingRetain([NSPropertyListSerialization dataWithPropertyList:resultDict format:NSPropertyListBinaryFormat_v1_0 options:kNilOptions error:nil]);
SInt32 respStatus =
CFMessagePortSendRequest(
_serverPort,
0x1113 /* executor put response */,
resultData,
1.0,
1.0,
kCFRunLoopDefaultMode /* wait for reply */,
NULL /* no return value */
);
CFRelease(resultData);
if (respStatus != kCFMessagePortSuccess) {
fprintf(stderr, "CFMessagePortSendRequest %d\n", respStatus);
}
}
}
%ctor {
NSString *bundleIdentifier = [[NSBundle mainBundle] bundleIdentifier];
if ([bundleIdentifier isEqualToString:@"com.apple.springboard"]) {
rocketbootstrap_unlock("com.darwindev.savt.port");
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_serverPort = CFMessagePortCreateLocal(
nil,
CFSTR("com.darwindev.savt.port"),
ServerCallback,
nil,
nil
);
});
CFRunLoopSourceRef runLoopSource =
CFMessagePortCreateRunLoopSource(kCFAllocatorDefault, _serverPort, 0);
CFRunLoopAddSource(
CFRunLoopGetCurrent(),
runLoopSource,
kCFRunLoopCommonModes
);
rocketbootstrap_cfmessageportexposelocal(_serverPort);
} else {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_serverPort = rocketbootstrap_cfmessageportcreateremote(nil, CFSTR("com.darwindev.savt.port"));
});
// assert(_serverPort);
if (_serverPort) {
CFNotificationCenterRef darwin = CFNotificationCenterGetDarwinNotifyCenter();
CFNotificationCenterAddObserver(darwin, NULL, ClientDidPutArguments, CFSTR("com.darwindev.savt.notify.client_put_arguments"), NULL, CFNotificationSuspensionBehaviorCoalesce);
}
}
}