]> git.saurik.com Git - safemode-ios.git/blame - MobileSafety.mm
Numerous random fixes.
[safemode-ios.git] / MobileSafety.mm
CommitLineData
25f84761
JF
1/* Cydia Substrate - Meta-Library Insert for iPhoneOS
2 * Copyright (C) 2008 Jay Freeman (saurik)
3*/
4
5/*
6 * Redistribution and use in source and binary
7 * forms, with or without modification, are permitted
8 * provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the
11 * above copyright notice, this list of conditions
12 * and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the
14 * above copyright notice, this list of conditions
15 * and the following disclaimer in the documentation
16 * and/or other materials provided with the
17 * distribution.
18 * 3. The name of the author may not be used to endorse
19 * or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS''
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
24 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
32 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
33 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
34 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
35 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36*/
37
38#import <CoreFoundation/CoreFoundation.h>
39#import <Foundation/Foundation.h>
40#import <CoreGraphics/CGGeometry.h>
41
42#include <substrate.h>
43
44@protocol MobileSubstrate
45- (id) sharedInstance;
46- (void) activateAlertItem:(id)item;
47- (id) initWithTitle:(NSString *)title body:(NSString *)body;
48- (id) ms$initWithSize:(CGSize)size;
49- (void) ms$drawRect:(CGRect)rect;
50- (id) darkGrayColor;
51- (void) setBackgroundColor:(id)color;
52- (int) ms$maxIconColumns;
53@end
54
55static void MSAlert(id self, SEL sel) {
56 static bool loaded = false;
57 if (!loaded)
58 loaded = true;
59 else return;
60
61 [[(id) objc_getClass("SBAlertItemsController") sharedInstance] activateAlertItem:
62 [[(id) objc_getClass("SBDismissOnlyAlertItem") alloc]
63 initWithTitle:@"Mobile Substrate Safe Mode"
dd869b95 64 body:@"We apologize for the inconvenience, but SpringBoard has just crashed.\n\nA recent software installation, upgrade, or removal might have been the cause of this.\n\nIf you are using IntelliScreen, then it probably crashed.\n\nYour device is now running in Safe Mode. All extensions that support this safety system are disabled.\n\nReboot (or restart SpringBoard) to return to the normal mode."
25f84761
JF
65 ]];
66}
67
68static int SBButtonBar$maxIconColumns(id<MobileSubstrate> self, SEL sel) {
69 static int max;
70 if (max == 0) {
71 max = [self ms$maxIconColumns];
72 if (NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults])
73 if (NSDictionary *iconState = [defaults objectForKey:@"iconState"])
74 if (NSDictionary *buttonBar = [iconState objectForKey:@"buttonBar"])
75 if (NSArray *iconMatrix = [buttonBar objectForKey:@"iconMatrix"])
76 if ([iconMatrix count] != 0)
77 if (NSArray *row = [iconMatrix objectAtIndex:0]) {
78 int count([row count]);
79 if (max < count)
80 max = count;
81 }
82 } return max;
83}
84
85static id SBContentLayer$initWithSize$(id<MobileSubstrate> self, SEL sel, CGSize size) {
86 self = [self ms$initWithSize:size];
87 if (self == nil)
88 return nil;
89 [self setBackgroundColor:[(id) objc_getClass("UIColor") darkGrayColor]];
90 return self;
91}
92
93static void SBStatusBarTimeView$drawRect$(id<MobileSubstrate> self, SEL sel, CGRect rect) {
94 id &_time(MSHookIvar<id>(self, "_time"));
95 if (_time != nil)
96 [_time autorelease];
97 _time = [@"Safe Mode" retain];
98 return [self ms$drawRect:rect];
99}
100
101#define Dylib_ "/Library/MobileSubstrate/MobileSubstrate.dylib"
102
103extern "C" void MSSafety() {
104 NSLog(@"MS:Warning: Entering Safe Mode");
105
106 MSHookMessage(objc_getClass("SBButtonBar"), @selector(maxIconColumns), (IMP) &SBButtonBar$maxIconColumns, "ms$");
107 MSHookMessage(objc_getClass("SBContentLayer"), @selector(initWithSize:), (IMP) &SBContentLayer$initWithSize$, "ms$");
108 MSHookMessage(objc_getClass("SBStatusBarTimeView"), @selector(drawRect:), (IMP) &SBStatusBarTimeView$drawRect$, "ms$");
109
110 char *dil = getenv("DYLD_INSERT_LIBRARIES");
111 if (dil == NULL)
112 NSLog(@"MS:Error: DYLD_INSERT_LIBRARIES is unset?");
113 else {
114 NSArray *dylibs([[NSString stringWithUTF8String:dil] componentsSeparatedByString:@":"]);
115 NSUInteger index([dylibs indexOfObject:@ Dylib_]);
116 if (index == NSNotFound)
117 NSLog(@"MS:Error: dylib not in DYLD_INSERT_LIBRARIES?");
118 else if ([dylibs count] == 1)
119 unsetenv("DYLD_INSERT_LIBRARIES");
120 else {
121 NSMutableArray *value([[[NSMutableArray alloc] init] autorelease]);
122 [value setArray:dylibs];
123 [value removeObjectAtIndex:index];
124 setenv("DYLD_INSERT_LIBRARIES", [[value componentsJoinedByString:@":"] UTF8String], !0);
125 }
126 }
127
128 if (Class _class = objc_getClass("SBIconController")) {
129 SEL sel(@selector(showInfoAlertIfNeeded));
130 if (Method method = class_getInstanceMethod(_class, sel))
131 method_setImplementation(method, (IMP) &MSAlert);
132 }
133}