diff --git a/RootHelper/control b/RootHelper/control
index 10e25ffd..546e6373 100644
--- a/RootHelper/control
+++ b/RootHelper/control
@@ -1,6 +1,6 @@
Package: com.opa334.trollstoreroothelper
Name: trollstoreroothelper
-Version: 1.4.3
+Version: 1.4.4
Architecture: iphoneos-arm
Description: An awesome tool of some sort!!
Maintainer: opa334
diff --git a/RootHelper/main.m b/RootHelper/main.m
index 55724625..88b7284c 100644
--- a/RootHelper/main.m
+++ b/RootHelper/main.m
@@ -620,96 +620,99 @@ int installApp(NSString* appPackagePath, BOOL sign, BOOL force, BOOL isTSUpdate)
if(signRet != 0) return signRet;
}
- LSApplicationProxy* existingAppProxy = [LSApplicationProxy applicationProxyForIdentifier:appId];
- if(existingAppProxy.installed)
- {
- // App update
- // Replace existing bundle with new version
-
- // Check if the existing app bundle is empty
- BOOL appBundleExists = existingAppProxy.bundleURL && [existingAppProxy.bundleURL checkResourceIsReachableAndReturnError:nil];
+ loadMCMFramework();
- // LSBundleProxy also has a bundleContainerURL property, but unforunately it is unreliable and just nil most of the time
- NSURL* bundleContainerURL = existingAppProxy.bundleURL.URLByDeletingLastPathComponent;
+ BOOL existed;
+ NSError* mcmError;
+ MCMAppContainer* appContainer = [objc_getClass("MCMAppContainer") containerWithIdentifier:appId createIfNecessary:YES existed:&existed error:&mcmError];
+ if(!appContainer || mcmError)
+ {
+ NSLog(@"[installApp] failed to create app container for %@: %@", appId, mcmError);
+ return 170;
+ }
- // Make sure the installed app is a TrollStore app or the container is empty (or the force flag is set)
- NSURL* trollStoreMarkURL = [bundleContainerURL URLByAppendingPathComponent:@"_TrollStore"];
- if(appBundleExists && ![trollStoreMarkURL checkResourceIsReachableAndReturnError:nil] && !force)
- {
- NSLog(@"[installApp] already installed and not a TrollStore app... bailing out");
- return 171;
- }
+ if(existed)
+ {
+ NSLog(@"[installApp] got existing app container: %@", appContainer);
+ }
+ else
+ {
+ NSLog(@"[installApp] created app container: %@", appContainer);
+ }
- // Terminate app if it's still running
- if(!isTSUpdate)
+ // check if the bundle is empty
+ BOOL isEmpty = YES;
+ NSArray* bundleItems = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:appContainer.url.path error:nil];
+ for(NSString* bundleItem in bundleItems)
+ {
+ if([bundleItem.pathExtension isEqualToString:@"app"])
{
- BKSTerminateApplicationForReasonAndReportWithDescription(appId, 5, false, @"TrollStore - App updated");
+ isEmpty = NO;
+ break;
}
+ }
- NSLog(@"[installApp] replacing existing app with new version");
-
- // Delete existing .app directory if it exists
- if(appBundleExists)
- {
- [[NSFileManager defaultManager] removeItemAtURL:existingAppProxy.bundleURL error:nil];
- }
+ NSLog(@"[installApp] container is empty? %d", isEmpty);
- // Install new version into existing app bundle
- NSError* copyError;
- BOOL suc = [[NSFileManager defaultManager] copyItemAtPath:appBundlePath toPath:[bundleContainerURL.path stringByAppendingPathComponent:appBundlePath.lastPathComponent] error:©Error];
- if(!suc)
- {
- NSLog(@"[installApp] Error copying new version during update: %@", copyError);
- return 178;
- }
+ // Make sure there isn't already an app store app installed with the same identifier
+ NSURL* trollStoreMarkURL = [appContainer.url URLByAppendingPathComponent:@"_TrollStore"];
+ if(existed && !isEmpty && ![trollStoreMarkURL checkResourceIsReachableAndReturnError:nil] && !force)
+ {
+ NSLog(@"[installApp] already installed and not a TrollStore app... bailing out");
+ return 171;
}
- else
+
+ // Mark app as TrollStore app
+ BOOL marked = [[NSFileManager defaultManager] createFileAtPath:trollStoreMarkURL.path contents:[NSData data] attributes:nil];
+ if(!marked)
{
- // Initial app install
- // Do initial placeholder installation using LSApplicationWorkspace
+ NSLog(@"[installApp] failed to mark %@ as TrollStore app", appId);
+ return 177;
+ }
- NSError* installError;
- BOOL suc = NO;
- @try
- {
- suc = [[LSApplicationWorkspace defaultWorkspace] installApplication:[NSURL fileURLWithPath:appPackagePath] withOptions:@{
- LSInstallTypeKey : @1,
- @"PackageType" : @"Placeholder"
- } error:&installError];
- }
- @catch(NSException* e)
+ fixPermissionsOfAppBundle(appBundlePath);
+
+ // Wipe old version if needed
+ if(existed)
+ {
+ if(![appId isEqualToString:@"com.opa334.TrollStore"])
{
- NSLog(@"[installApp] encountered expection %@ while trying to do placeholder install", e);
- suc = NO;
+ BKSTerminateApplicationForReasonAndReportWithDescription(appId, 5, false, @"TrollStore - App updated");
}
-
- if(!suc)
+
+ NSLog(@"[installApp] found existing TrollStore app, cleaning directory");
+ NSDirectoryEnumerator *enumerator = [[NSFileManager defaultManager] enumeratorAtURL:appContainer.url includingPropertiesForKeys:nil options:0 errorHandler:nil];
+ NSURL* fileURL;
+ while(fileURL = [enumerator nextObject])
{
- NSLog(@"[installApp] encountered error %@ while trying to do placeholder install", installError);
- return 180;
- }
+ // do not under any circumstance delete this file as it makes iOS loose the app registration
+ if([fileURL.lastPathComponent isEqualToString:@".com.apple.mobile_container_manager.metadata.plist"] || [fileURL.lastPathComponent isEqualToString:@"_TrollStore"])
+ {
+ NSLog(@"[installApp] skipping removal of %@", fileURL);
+ continue;
+ }
- // Get newly installed proxy
- existingAppProxy = [LSApplicationProxy applicationProxyForIdentifier:appId];
+ [[NSFileManager defaultManager] removeItemAtURL:fileURL error:nil];
+ }
}
- // Mark app as TrollStore app
- NSURL* bundleContainerURL = existingAppProxy.bundleURL.URLByDeletingLastPathComponent;
- NSURL* trollStoreMarkURL = [bundleContainerURL URLByAppendingPathComponent:@"_TrollStore"];
- if(![[NSFileManager defaultManager] fileExistsAtPath:trollStoreMarkURL.path])
+ // Install app
+ NSString* newAppBundlePath = [appContainer.url.path stringByAppendingPathComponent:appBundlePath.lastPathComponent];
+ NSLog(@"[installApp] new app path: %@", newAppBundlePath);
+
+ NSError* copyError;
+ BOOL suc = [[NSFileManager defaultManager] copyItemAtPath:appBundlePath toPath:newAppBundlePath error:©Error];
+ if(suc)
{
- BOOL marked = [[NSFileManager defaultManager] createFileAtPath:trollStoreMarkURL.path contents:[NSData data] attributes:nil];
- if(!marked)
- {
- NSLog(@"[installApp] failed to mark %@ as TrollStore app", appId);
- return 177;
- }
+ NSLog(@"[installApp] App %@ installed, adding to icon cache now...", appId);
+ registerPath((char*)newAppBundlePath.fileSystemRepresentation, 0, YES);
+ return 0;
+ }
+ else
+ {
+ NSLog(@"[installApp] Failed to copy app bundle for app %@, error: %@", appId, copyError);
+ return 178;
}
-
- // At this point the (new version of the) app is installed but still needs to be registered
- // Also permissions need to be fixed
- fixPermissionsOfAppBundle(existingAppProxy.bundleURL.path);
- registerPath((char*)existingAppProxy.bundleURL.path.fileSystemRepresentation, 0, YES);
}
int uninstallApp(NSString* appPath, NSString* appId)
diff --git a/TrollHelper/Resources/Info.plist b/TrollHelper/Resources/Info.plist
index 4c299a06..841e1f68 100644
--- a/TrollHelper/Resources/Info.plist
+++ b/TrollHelper/Resources/Info.plist
@@ -52,7 +52,7 @@
iPhoneOS
CFBundleVersion
- 1.4.3
+ 1.4.4
LSRequiresIPhoneOS
UIDeviceFamily
diff --git a/TrollHelper/control b/TrollHelper/control
index 40401ff8..2599b4c6 100644
--- a/TrollHelper/control
+++ b/TrollHelper/control
@@ -1,6 +1,6 @@
Package: com.opa334.trollstorehelper
Name: TrollStore Helper
-Version: 1.4.3
+Version: 1.4.4
Architecture: iphoneos-arm
Description: Helper utility to install and manage TrollStore!
Maintainer: opa334
diff --git a/TrollStore/Resources/Info.plist b/TrollStore/Resources/Info.plist
index c28013f0..6dfed0dd 100644
--- a/TrollStore/Resources/Info.plist
+++ b/TrollStore/Resources/Info.plist
@@ -50,7 +50,7 @@
iPhoneOS
CFBundleVersion
- 1.4.3
+ 1.4.4
LSRequiresIPhoneOS
UIDeviceFamily
diff --git a/TrollStore/TSApplicationsManager.m b/TrollStore/TSApplicationsManager.m
index b5851326..14206b67 100644
--- a/TrollStore/TSApplicationsManager.m
+++ b/TrollStore/TSApplicationsManager.m
@@ -67,9 +67,6 @@ - (NSError*)errorForCode:(int)code
case 179:
errorDescription = @"The app you tried to install has the same identifier as a system app already installed on the device. The installation has been prevented to protect you from possible bootloops or other issues.";
break;
- case 180:
- errorDescription = @"The LSApplicationWorkspace app installation failed.";
- break;
}
NSError* error = [NSError errorWithDomain:TrollStoreErrorDomain code:code userInfo:@{NSLocalizedDescriptionKey : errorDescription}];
diff --git a/TrollStore/control b/TrollStore/control
index f9e0f163..216dd237 100644
--- a/TrollStore/control
+++ b/TrollStore/control
@@ -1,6 +1,6 @@
Package: com.opa334.trollstore
Name: TrollStore
-Version: 1.4.3
+Version: 1.4.4
Architecture: iphoneos-arm
Description: An awesome application!
Maintainer: opa334