SameBoy | Accurate GB/GBC emulator |
| download: https://git.y1.nz/archives/sameboy.tar.gz | |
| README | Files | Log | Refs | LICENSE |
iOS/installer.m
1 #import <Foundation/Foundation.h>
2 #import <dlfcn.h>
3 #import <objc/runtime.h>
4
5 @interface LSApplicationProxy : NSObject
6 @property (readonly, getter=isContainerized) bool containerized;
7 @property (readonly) NSString *bundleIdentifier;
8 @property (readonly) NSURL * bundleURL;
9 @end
10
11 @interface LSApplicationWorkspace : NSObject
12 + (instancetype)defaultWorkspace;
13 - (NSArray <LSApplicationProxy *> *)allInstalledApplications;
14 - (bool)unregisterApplication:(NSURL *)url;
15 - (bool)registerApplicationDictionary:(NSDictionary *)dict;
16 @end
17
18 @interface MCMAppDataContainer : NSObject
19 + (MCMAppDataContainer *)containerWithIdentifier:(NSString *)identifier
20 createIfNecessary:(bool)create
21 existed:(bool *)existed
22 error:(NSError **)error;
23 @property(readonly) NSURL *url;
24 @end
25
26
27 int main(int argc, char **argv)
28 {
29 if (argc != 2) return 1;
30 // Make sure MobileContainerManager is loaded
31 if (!dlopen("/System/Library/PrivateFrameworks/MobileContainerManager.framework/MobileContainerManager", RTLD_NOW)) return 1;
32
33 bool uninstall = false;
34 if (strcmp(argv[1], "uninstall") == 0) {
35 uninstall = true;
36 }
37 else if (strcmp(argv[1], "install") != 0) {
38 return 1;
39 }
40
41 NSString *installPath = @"/var/jb/Applications/SameBoy-iOS.app";
42 if (access("/Applications/", W_OK) == 0) {
43 installPath = @"/Applications/SameBoy-iOS.app";
44 }
45 NSLog(@"Install path is %@", installPath);
46
47 for (LSApplicationProxy *app in [[LSApplicationWorkspace defaultWorkspace] allInstalledApplications]) {
48 if (![app.bundleIdentifier isEqualToString:[NSBundle mainBundle].bundleIdentifier]) continue;
49 if (![app.bundleURL.path.stringByResolvingSymlinksInPath isEqual:installPath.stringByResolvingSymlinksInPath]) {
50 // Already installed elsewhere
51 NSLog(@"Already installed at %@", app.bundleURL.path);
52 return 1;
53 }
54
55 NSLog(@"Unregistering previous installation");
56 // We're registered but not containerized (or just uninstalling), unregister ourselves first
57 if (![[LSApplicationWorkspace defaultWorkspace] unregisterApplication:app.bundleURL]) return 1;
58
59 break;
60 }
61
62 // Don't modify files if we're at the correct path already
63 if (uninstall || ![[NSBundle mainBundle].bundlePath.stringByResolvingSymlinksInPath isEqual:installPath.stringByResolvingSymlinksInPath]) {
64 // Remove any previous copy
65 NSError *error = nil;
66 if (!access(installPath.UTF8String, F_OK)) {
67 NSLog(@"Removing previous installation");
68 [[NSFileManager defaultManager] removeItemAtPath:installPath error:&error];
69 if (error) {
70 NSLog(@"Error: %@", error);
71 return 1;
72 }
73 }
74
75 // If we're uninstalling, we're done
76 if (uninstall) return 0;
77
78 NSLog(@"Installing...");
79
80 [[NSFileManager defaultManager] moveItemAtPath:[NSBundle mainBundle].bundlePath toPath:installPath error:&error];
81 if (error) {
82 NSLog(@"Error: %@", error);
83 return 1;
84 }
85 }
86
87
88 NSLog(@"Registering...");
89
90 NSString *container = [objc_getClass("MCMAppDataContainer") containerWithIdentifier:[NSBundle mainBundle].bundleIdentifier
91 createIfNecessary:true
92 existed:nil
93 error:nil].url.path;
94
95 return ![[LSApplicationWorkspace defaultWorkspace] registerApplicationDictionary:@{
96 @"ApplicationType": @"System",
97 @"CFBundleIdentifier": [NSBundle mainBundle].bundleIdentifier,
98 @"CompatibilityState": @NO,
99 @"Container": container,
100 @"IsDeletable": @NO,
101 @"Path": installPath,
102 @"_LSBundlePlugins": @{},
103 @"IsContainerized": @YES,
104 }];
105 }
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.