diff --git a/RootHelper/control b/RootHelper/control index 10e25ff..546e637 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 5572462..88b7284 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) + loadMCMFramework(); + + BOOL existed; + NSError* mcmError; + MCMAppContainer* appContainer = [objc_getClass("MCMAppContainer") containerWithIdentifier:appId createIfNecessary:YES existed:&existed error:&mcmError]; + if(!appContainer || mcmError) { - // App update - // Replace existing bundle with new version + NSLog(@"[installApp] failed to create app container for %@: %@", appId, mcmError); + return 170; + } - // Check if the existing app bundle is empty - BOOL appBundleExists = existingAppProxy.bundleURL && [existingAppProxy.bundleURL checkResourceIsReachableAndReturnError:nil]; + if(existed) + { + NSLog(@"[installApp] got existing app container: %@", appContainer); + } + else + { + NSLog(@"[installApp] created app container: %@", appContainer); + } - // LSBundleProxy also has a bundleContainerURL property, but unforunately it is unreliable and just nil most of the time - NSURL* bundleContainerURL = existingAppProxy.bundleURL.URLByDeletingLastPathComponent; - - // 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) + // 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"]) { - NSLog(@"[installApp] already installed and not a TrollStore app... bailing out"); - return 171; + isEmpty = NO; + break; } + } - // Terminate app if it's still running - if(!isTSUpdate) + NSLog(@"[installApp] container is empty? %d", isEmpty); + + // 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; + } + + // Mark app as TrollStore app + 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; + } + + fixPermissionsOfAppBundle(appBundlePath); + + // Wipe old version if needed + if(existed) + { + if(![appId isEqualToString:@"com.opa334.TrollStore"]) { BKSTerminateApplicationForReasonAndReportWithDescription(appId, 5, false, @"TrollStore - App updated"); } - NSLog(@"[installApp] replacing existing app with new version"); - - // Delete existing .app directory if it exists - if(appBundleExists) + 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]) { - [[NSFileManager defaultManager] removeItemAtURL:existingAppProxy.bundleURL error:nil]; - } + // 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; + } - // 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; + [[NSFileManager defaultManager] removeItemAtURL:fileURL error:nil]; } } + + // 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) + { + NSLog(@"[installApp] App %@ installed, adding to icon cache now...", appId); + registerPath((char*)newAppBundlePath.fileSystemRepresentation, 0, YES); + return 0; + } else { - // Initial app install - // Do initial placeholder installation using LSApplicationWorkspace - - NSError* installError; - BOOL suc = NO; - @try - { - suc = [[LSApplicationWorkspace defaultWorkspace] installApplication:[NSURL fileURLWithPath:appPackagePath] withOptions:@{ - LSInstallTypeKey : @1, - @"PackageType" : @"Placeholder" - } error:&installError]; - } - @catch(NSException* e) - { - NSLog(@"[installApp] encountered expection %@ while trying to do placeholder install", e); - suc = NO; - } - - if(!suc) - { - NSLog(@"[installApp] encountered error %@ while trying to do placeholder install", installError); - return 180; - } - - // Get newly installed proxy - existingAppProxy = [LSApplicationProxy applicationProxyForIdentifier:appId]; + NSLog(@"[installApp] Failed to copy app bundle for app %@, error: %@", appId, copyError); + return 178; } - - // Mark app as TrollStore app - NSURL* bundleContainerURL = existingAppProxy.bundleURL.URLByDeletingLastPathComponent; - NSURL* trollStoreMarkURL = [bundleContainerURL URLByAppendingPathComponent:@"_TrollStore"]; - if(![[NSFileManager defaultManager] fileExistsAtPath:trollStoreMarkURL.path]) - { - 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; - } - } - - // 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 4c299a0..841e1f6 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 40401ff..2599b4c 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 c28013f..6dfed0d 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 b585132..14206b6 100644 --- a/TrollStore/TSApplicationsManager.m +++ b/TrollStore/TSApplicationsManager.m @@ -67,9 +67,6 @@ 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 f9e0f16..216dd23 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