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