From df28fd7ccfd1923dc49f94accc71a9b46a3bf88a Mon Sep 17 00:00:00 2001 From: "matthias.ringwald" Date: Wed, 16 Sep 2009 21:37:32 +0000 Subject: [PATCH] added CFMessagePort IPC --- SpringBoardAccess/Makefile.in | 24 +++++--- SpringBoardAccess/SpringBoardAccess-test.c | 20 +++++++ SpringBoardAccess/SpringBoardAccess.m | 14 ----- SpringBoardAccess/SpringBoardAccess.mm | 66 ++++++++++++++++++++++ 4 files changed, 101 insertions(+), 23 deletions(-) create mode 100644 SpringBoardAccess/SpringBoardAccess-test.c delete mode 100644 SpringBoardAccess/SpringBoardAccess.m create mode 100644 SpringBoardAccess/SpringBoardAccess.mm diff --git a/SpringBoardAccess/Makefile.in b/SpringBoardAccess/Makefile.in index 60a065633..8bcab6214 100644 --- a/SpringBoardAccess/Makefile.in +++ b/SpringBoardAccess/Makefile.in @@ -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) diff --git a/SpringBoardAccess/SpringBoardAccess-test.c b/SpringBoardAccess/SpringBoardAccess-test.c new file mode 100644 index 000000000..0ce45e8d6 --- /dev/null +++ b/SpringBoardAccess/SpringBoardAccess-test.c @@ -0,0 +1,20 @@ +#import + +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); +} + diff --git a/SpringBoardAccess/SpringBoardAccess.m b/SpringBoardAccess/SpringBoardAccess.m deleted file mode 100644 index 7b9f0f8a5..000000000 --- a/SpringBoardAccess/SpringBoardAccess.m +++ /dev/null @@ -1,14 +0,0 @@ -// -// SpringBoardAccess.m -// -// Created by Matthias Ringwald on 9/15/09. -// - -#import -#import - -#import "../3rdparty/substrate.h" - -void SpringBoardAccessInitialize(){ - NSLog(@"SpringBoardAccessInitialize called!"); -} diff --git a/SpringBoardAccess/SpringBoardAccess.mm b/SpringBoardAccess/SpringBoardAccess.mm new file mode 100644 index 000000000..190e3bae9 --- /dev/null +++ b/SpringBoardAccess/SpringBoardAccess.mm @@ -0,0 +1,66 @@ +// +// SpringBoardAccess.m +// +// Created by Matthias Ringwald on 9/15/09. +// + +#import +#import + +#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]; +}