diff --git a/Makefile b/Makefile
index 6e39fc0..5679496 100644
--- a/Makefile
+++ b/Makefile
@@ -244,7 +244,7 @@ CORE_FILTER += Core/debugger.c Core/sm83_disassembler.c Core/symbol_hash.c
LDFLAGS += -arch arm64
OCFLAGS += -x objective-c -fobjc-arc -Wno-deprecated-declarations -isysroot $(SYSROOT)
LDFLAGS += -miphoneos-version-min=11.0 -isysroot $(SYSROOT)
-REREGISTER_LDFLAGS := $(LDFLAGS) -lobjc -framework CoreServices -framework Foundation
+IOS_INSTALLER_LDFLAGS := $(LDFLAGS) -lobjc -framework CoreServices -framework Foundation
LDFLAGS += -lobjc -framework UIKit -framework Foundation -framework CoreGraphics -framework Metal -framework MetalKit -framework AudioToolbox -framework AVFoundation -framework QuartzCore -framework CoreMotion -framework CoreVideo -framework CoreMedia -framework CoreImage -framework UserNotifications -weak_framework CoreHaptics
CODESIGN := codesign -fs -
else
@@ -325,7 +325,7 @@ quicklook: $(BIN)/SameBoy.qlgenerator
sdl: $(SDL_TARGET) $(BIN)/SDL/dmg_boot.bin $(BIN)/SDL/mgb_boot.bin $(BIN)/SDL/cgb0_boot.bin $(BIN)/SDL/cgb_boot.bin $(BIN)/SDL/agb_boot.bin $(BIN)/SDL/sgb_boot.bin $(BIN)/SDL/sgb2_boot.bin $(BIN)/SDL/LICENSE $(BIN)/SDL/registers.sym $(BIN)/SDL/background.bmp $(BIN)/SDL/Shaders $(BIN)/SDL/Palettes
bootroms: $(BIN)/BootROMs/agb_boot.bin $(BIN)/BootROMs/cgb_boot.bin $(BIN)/BootROMs/cgb0_boot.bin $(BIN)/BootROMs/dmg_boot.bin $(BIN)/BootROMs/mgb_boot.bin $(BIN)/BootROMs/sgb_boot.bin $(BIN)/BootROMs/sgb2_boot.bin
tester: $(TESTER_TARGET) $(BIN)/tester/dmg_boot.bin $(BIN)/tester/cgb_boot.bin $(BIN)/tester/agb_boot.bin $(BIN)/tester/sgb_boot.bin $(BIN)/tester/sgb2_boot.bin
-_ios: $(BIN)/SameBoy-iOS.app $(OBJ)/reregister
+_ios: $(BIN)/SameBoy-iOS.app $(OBJ)/installer
ios-ipa: $(BIN)/SameBoy-iOS.ipa
ios-deb: $(BIN)/SameBoy-iOS.deb
ifeq ($(PLATFORM),windows32)
@@ -344,7 +344,7 @@ CORE_SOURCES := $(filter-out $(CORE_FILTER),$(shell ls Core/*.c))
CORE_HEADERS := $(shell ls Core/*.h)
SDL_SOURCES := $(shell ls SDL/*.c) $(OPEN_DIALOG) $(patsubst %,SDL/audio/%.c,$(SDL_AUDIO_DRIVERS))
TESTER_SOURCES := $(shell ls Tester/*.c)
-IOS_SOURCES := $(filter-out iOS/reregister.m, $(shell ls iOS/*.m)) $(shell ls AppleCommon/*.m)
+IOS_SOURCES := $(filter-out iOS/installer.m, $(shell ls iOS/*.m)) $(shell ls AppleCommon/*.m)
COCOA_SOURCES := $(shell ls Cocoa/*.m) $(shell ls HexFiend/*.m) $(shell ls JoyKit/*.m) $(shell ls AppleCommon/*.m)
QUICKLOOK_SOURCES := $(shell ls QuickLook/*.m) $(shell ls QuickLook/*.c)
@@ -449,9 +449,8 @@ ifeq ($(CONF), release)
$(STRIP) $@
endif
-$(OBJ)/reregister: iOS/reregister.m iOS/reregister.entitlements
- $(CC) $< -o $@ $(REREGISTER_LDFLAGS) $(CFLAGS)
- codesign -fs - --entitlements iOS/reregister.entitlements $@
+$(OBJ)/installer: iOS/installer.m
+ $(CC) $< -o $@ $(IOS_INSTALLER_LDFLAGS) $(CFLAGS)
# Cocoa Port
@@ -697,20 +696,22 @@ $(BIN)/SameBoy-iOS.deb: $(OBJ)/debian-binary $(OBJ)/control.tar.gz $(OBJ)/data.t
-@$(MKDIR) -p $(dir $@)
(cd $(OBJ) && ar cr $(abspath $@) $(notdir $^))
-$(OBJ)/data.tar.gz: ios iOS/jailbreak.entitlements
- $(MKDIR) -p $(OBJ)/Applications
- cp -rf $(BIN)/SameBoy-iOS.app $(OBJ)/Applications/SameBoy-iOS.app
- cp build/obj-ios/reregister $(OBJ)/Applications/SameBoy-iOS.app
- codesign -fs - --entitlements iOS/jailbreak.entitlements $(OBJ)/Applications/SameBoy-iOS.app
- (cd $(OBJ) && tar -czf $(abspath $@) --format ustar --uid 501 --gid 501 --numeric-owner ./Applications)
- rm -rf $(OBJ)/Applications
+$(OBJ)/data.tar.gz: ios iOS/jailbreak.entitlements iOS/installer.entitlements
+ $(MKDIR) -p $(OBJ)/private/var/containers/
+ cp -rf $(BIN)/SameBoy-iOS.app $(OBJ)/private/var/containers/SameBoy-iOS.app
+ cp build/obj-ios/installer $(OBJ)/private/var/containers/SameBoy-iOS.app
+ codesign -fs - --entitlements iOS/installer.entitlements $(OBJ)/private/var/containers/SameBoy-iOS.app/installer
+ codesign -fs - --entitlements iOS/jailbreak.entitlements $(OBJ)/private/var/containers/SameBoy-iOS.app
+ (cd $(OBJ) && tar -czf $(abspath $@) --format ustar --uid 501 --gid 501 --numeric-owner ./private)
+ rm -rf $(OBJ)/private/
-$(OBJ)/control.tar.gz: iOS/deb-postinst iOS/deb-control
+$(OBJ)/control.tar.gz: iOS/deb-postinst iOS/deb-prerm iOS/deb-control
-@$(MKDIR) -p $(dir $@)
sed "s/@VERSION/$(VERSION)/" < iOS/deb-control > $(OBJ)/control
ln iOS/deb-postinst $(OBJ)/postinst
- (cd $(OBJ) && tar -czf $(abspath $@) --format ustar --uid 501 --gid 501 --numeric-owner ./control ./postinst)
- rm $(OBJ)/control $(OBJ)/postinst
+ ln iOS/deb-prerm $(OBJ)/prerm
+ (cd $(OBJ) && tar -czf $(abspath $@) --format ustar --uid 501 --gid 501 --numeric-owner ./control ./postinst ./prerm)
+ rm $(OBJ)/control $(OBJ)/postinst $(OBJ)/prerm
$(OBJ)/debian-binary:
-@$(MKDIR) -p $(dir $@)
diff --git a/iOS/deb-control b/iOS/deb-control
index 7f3002e..4c92a80 100644
--- a/iOS/deb-control
+++ b/iOS/deb-control
@@ -1,7 +1,7 @@
Package: com.github.liji32.sameboy.ios
Name: SameBoy
Depends: firmware (>= 11.0)
-Architecture: iphoneos-arm
+Architecture: all
Description: A Game Boy emulator for iOS
Maintainer: Lior Halphon
Author: Lior Halphon
diff --git a/iOS/deb-postinst b/iOS/deb-postinst
index ed91d43..13dc0e2 100755
--- a/iOS/deb-postinst
+++ b/iOS/deb-postinst
@@ -1,2 +1,2 @@
#!/bin/bash
-/Applications/SameBoy-iOS.app/reregister
+/private/var/containers/SameBoy-iOS.app/installer install
diff --git a/iOS/deb-prerm b/iOS/deb-prerm
new file mode 100755
index 0000000..849f266
--- /dev/null
+++ b/iOS/deb-prerm
@@ -0,0 +1,2 @@
+#!/bin/bash
+/Applications/SameBoy-iOS.app/installer uninstall || /var/jb/Applications/SameBoy-iOS.app/installer uninstall
diff --git a/iOS/reregister.entitlements b/iOS/installer.entitlements
similarity index 89%
rename from iOS/reregister.entitlements
rename to iOS/installer.entitlements
index c1ed56b..5dd0f8a 100644
--- a/iOS/reregister.entitlements
+++ b/iOS/installer.entitlements
@@ -15,5 +15,7 @@
platform-application
+com.apple.private.security.no-container
+
\ No newline at end of file
diff --git a/iOS/installer.m b/iOS/installer.m
new file mode 100644
index 0000000..2fa2ff6
--- /dev/null
+++ b/iOS/installer.m
@@ -0,0 +1,105 @@
+#import
+#import
+#import
+
+@interface LSApplicationProxy : NSObject
+@property (readonly, getter=isContainerized) bool containerized;
+@property (readonly) NSString *bundleIdentifier;
+@property (readonly) NSURL * bundleURL;
+@end
+
+@interface LSApplicationWorkspace : NSObject
++ (instancetype)defaultWorkspace;
+- (NSArray *)allInstalledApplications;
+- (bool)unregisterApplication:(NSURL *)url;
+- (bool)registerApplicationDictionary:(NSDictionary *)dict;
+@end
+
+@interface MCMAppDataContainer : NSObject
++ (MCMAppDataContainer *)containerWithIdentifier:(NSString *)identifier
+ createIfNecessary:(bool)create
+ existed:(bool *)existed
+ error:(NSError **)error;
+@property(readonly) NSURL *url;
+@end
+
+
+int main(int argc, char **argv)
+{
+ if (argc != 2) return 1;
+ // Make sure MobileContainerManager is loaded
+ if (!dlopen("/System/Library/PrivateFrameworks/MobileContainerManager.framework/MobileContainerManager", RTLD_NOW)) return 1;
+
+ bool uninstall = false;
+ if (strcmp(argv[1], "uninstall") == 0) {
+ uninstall = true;
+ }
+ else if (strcmp(argv[1], "install") != 0) {
+ return 1;
+ }
+
+ NSString *installPath = @"/var/jb/Applications/SameBoy-iOS.app";
+ if (access("/Applications/", W_OK) == 0) {
+ installPath = @"/Applications/SameBoy-iOS.app";
+ }
+ NSLog(@"Install path is %@", installPath);
+
+ for (LSApplicationProxy *app in [[LSApplicationWorkspace defaultWorkspace] allInstalledApplications]) {
+ if (![app.bundleIdentifier isEqualToString:[NSBundle mainBundle].bundleIdentifier]) continue;
+ if (![app.bundleURL.path.stringByResolvingSymlinksInPath isEqual:installPath.stringByResolvingSymlinksInPath]) {
+ // Already installed elsewhere
+ NSLog(@"Already installed at %@", app.bundleURL.path);
+ return 1;
+ }
+
+ NSLog(@"Unregistering previous installation");
+ // We're registered but not containerized (or just uninstalling), unregister ourselves first
+ if (![[LSApplicationWorkspace defaultWorkspace] unregisterApplication:app.bundleURL]) return 1;
+
+ break;
+ }
+
+ // Don't modify files if we're at the correct path already
+ if (uninstall || ![[NSBundle mainBundle].bundlePath.stringByResolvingSymlinksInPath isEqual:installPath.stringByResolvingSymlinksInPath]) {
+ // Remove any previous copy
+ NSError *error = nil;
+ if (!access(installPath.UTF8String, F_OK)) {
+ NSLog(@"Removing previous installation");
+ [[NSFileManager defaultManager] removeItemAtPath:installPath error:&error];
+ if (error) {
+ NSLog(@"Error: %@", error);
+ return 1;
+ }
+ }
+
+ // If we're uninstalling, we're done
+ if (uninstall) return 0;
+
+ NSLog(@"Installing...");
+
+ [[NSFileManager defaultManager] moveItemAtPath:[NSBundle mainBundle].bundlePath toPath:installPath error:&error];
+ if (error) {
+ NSLog(@"Error: %@", error);
+ return 1;
+ }
+ }
+
+
+ NSLog(@"Registering...");
+
+ NSString *container = [objc_getClass("MCMAppDataContainer") containerWithIdentifier:[NSBundle mainBundle].bundleIdentifier
+ createIfNecessary:true
+ existed:nil
+ error:nil].url.path;
+
+ return ![[LSApplicationWorkspace defaultWorkspace] registerApplicationDictionary:@{
+ @"ApplicationType": @"System",
+ @"CFBundleIdentifier": [NSBundle mainBundle].bundleIdentifier,
+ @"CompatibilityState": @NO,
+ @"Container": container,
+ @"IsDeletable": @NO,
+ @"Path": installPath,
+ @"_LSBundlePlugins": @{},
+ @"IsContainerized": @YES,
+ }];
+}
diff --git a/iOS/reregister.m b/iOS/reregister.m
deleted file mode 100644
index 49885ba..0000000
--- a/iOS/reregister.m
+++ /dev/null
@@ -1,54 +0,0 @@
-#import
-#import
-#import
-
-@interface LSApplicationProxy : NSObject
-@property (nonatomic, readonly, getter=isContainerized) bool containerized;
-@property (nonatomic, readonly) NSString *bundleIdentifier;
-@end
-
-@interface LSApplicationWorkspace : NSObject
-+ (instancetype)defaultWorkspace;
-- (NSArray *)allInstalledApplications;
-- (bool)unregisterApplication:(NSURL *)url;
-- (bool)registerApplicationDictionary:(NSDictionary *)dict;
-@end
-
-@interface MCMAppDataContainer : NSObject
-+ (MCMAppDataContainer *)containerWithIdentifier:(NSString *)identifier
- createIfNecessary:(bool)create
- existed:(bool *)existed
- error:(NSError **)error;
-@property(readonly, nonatomic) NSURL *url;
-@end
-
-
-int main(void)
-{
- // Make sure MobileContainerManager is loaded
- if (!dlopen("/System/Library/PrivateFrameworks/MobileContainerManager.framework/MobileContainerManager", RTLD_NOW)) return 1;
- for (LSApplicationProxy *app in [[LSApplicationWorkspace defaultWorkspace] allInstalledApplications]) {
- if (![app.bundleIdentifier isEqualToString:[NSBundle mainBundle].bundleIdentifier]) continue;
- if (app.containerized) return 0; // Everything's fine, no need to reregister
- // We're registered but not containerized, unregister ourselves first
- if (![[LSApplicationWorkspace defaultWorkspace] unregisterApplication:[NSBundle mainBundle].bundleURL]) return 1;
-
- break;
- }
-
- NSString *container = [objc_getClass("MCMAppDataContainer") containerWithIdentifier:[NSBundle mainBundle].bundleIdentifier
- createIfNecessary:true
- existed:nil
- error:nil].url.path;
-
- return ![[LSApplicationWorkspace defaultWorkspace] registerApplicationDictionary:@{
- @"ApplicationType": @"System",
- @"CFBundleIdentifier": [NSBundle mainBundle].bundleIdentifier,
- @"CompatibilityState": @NO,
- @"Container": container,
- @"IsDeletable": @NO,
- @"Path": [NSBundle mainBundle].bundlePath,
- @"_LSBundlePlugins": @{},
- @"IsContainerized": @YES,
- }];
-}