added CFMessagePort IPC

This commit is contained in:
matthias.ringwald 2009-09-16 21:37:32 +00:00
parent c4e21bc48a
commit df28fd7ccf
4 changed files with 101 additions and 23 deletions

View File

@ -1,20 +1,26 @@
NAME = SpringBoardAccess
CC = @CC@
OBJC = @OBJC@
LDFLAGS = @LDFLAGS@
CPPFLAGS = @CPPFLAGS@
LDFLAGS += -lobjc \
-multiply_defined suppress \
-framework CoreFoundation \
-framework Foundation \
-framework UIKit \
-L../3rdparty -lsubstrate
LIB_LDFLAGS = -lobjc \
-multiply_defined suppress \
-framework CoreFoundation \
-framework Foundation \
-framework UIKit \
-L../3rdparty -lsubstrate
all: $(NAME).dylib
APP_LDFLAGS = -framework CoreFoundation
all: $(NAME).dylib $(NAME)-test
clean:
rm -f $(NAME).dylib
$(NAME).dylib: $(NAME).m
$(OBJC) $(CPPFLAGS) -dynamiclib -o $@ $(NAME).m -init _$(NAME)Initialize $(LDFLAGS)
$(NAME).dylib: $(NAME).mm
$(OBJC) $(CPPFLAGS) -dynamiclib -o $@ $(NAME).mm -init _$(NAME)Initialize $(LDFLAGS) $(LIB_LDFLAGS)
$(NAME)-test: $(NAME)-test.c
$(OBJC) $(CPPFLAGS) -o $@ $(NAME)-test.c $(LDFLAGS) $(APP_LDFLAGS)

View File

@ -0,0 +1,20 @@
#import <CoreFoundation/CoreFoundation.h>
main() {
CFMessagePortRef remote = CFMessagePortCreateRemote(NULL, CFSTR("SpringBoardAccess"));
if (!remote) {
printf("Failed to get remote port\n");
exit(10);
}
char *message = "Hello, world!";
CFDataRef data, returnData = NULL;
data = CFDataCreate(NULL, (const UInt8 *)message, strlen(message)+1);
if (kCFMessagePortSuccess == CFMessagePortSendRequest(remote, 0, data, 1, 1, kCFRunLoopDefaultMode, &returnData) && NULL != returnData) {
printf("here is our return data: %s\n",
CFDataGetBytePtr(returnData));
CFRelease(returnData);
}
CFRelease(data);
CFRelease(remote);
}

View File

@ -1,14 +0,0 @@
//
// SpringBoardAccess.m
//
// Created by Matthias Ringwald on 9/15/09.
//
#import <Foundation/Foundation.h>
#import <CoreFoundation/CoreFoundation.h>
#import "../3rdparty/substrate.h"
void SpringBoardAccessInitialize(){
NSLog(@"SpringBoardAccessInitialize called!");
}

View File

@ -0,0 +1,66 @@
//
// SpringBoardAccess.m
//
// Created by Matthias Ringwald on 9/15/09.
//
#import <Foundation/Foundation.h>
#import <CoreFoundation/CoreFoundation.h>
#import "../3rdparty/substrate.h"
#import "../3rdparty/SpringBoard.h"
#define HOOK(class, name, type, args...) \
static type (*_ ## class ## $ ## name)(class *self, SEL sel, ## args); \
static type $ ## class ## $ ## name(class *self, SEL sel, ## args)
#define CALL_ORIG(class, name, args...) \
_ ## class ## $ ## name(self, sel, ## args)
CFDataRef myCallBack(CFMessagePortRef local, SInt32 msgid, CFDataRef data, void *info) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
char *message = "Thanks for calling!";
CFDataRef returnData = CFDataCreate(NULL, (const UInt8 *) message, strlen(message)+1);
NSLog(@"here is our received data: %s\n", CFDataGetBytePtr(data));
[pool release];
return returnData; // as stated in header, both data and returnData will be released for us after callback returns
}
//______________________________________________________________________________
HOOK(SpringBoard, applicationDidFinishLaunching$, void, id app) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
CALL_ORIG(SpringBoard, applicationDidFinishLaunching$, app);
CFMessagePortRef local = CFMessagePortCreateLocal(NULL, CFSTR("SpringBoardAccess"), myCallBack, NULL, false);
CFRunLoopSourceRef source = CFMessagePortCreateRunLoopSource(NULL, local, 0);
CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopDefaultMode);
[pool release];
}
//______________________________________________________________________________
extern "C" void SpringBoardAccessInitialize(){
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
// NOTE: This library should only be loaded for SpringBoard
NSString *identifier = [[NSBundle mainBundle] bundleIdentifier];
if (![identifier isEqualToString:@"com.apple.springboard"])
return;
NSLog(@"SpringBoardAccessInitialize called for SpringBoard!");
// Setup hooks
Class $SpringBoard(objc_getClass("SpringBoard"));
_SpringBoard$applicationDidFinishLaunching$ =
MSHookMessage($SpringBoard, @selector(applicationDidFinishLaunching:), &$SpringBoard$applicationDidFinishLaunching$);
[pool release];
}