]> git.saurik.com Git - uikittools.git/blobdiff - extrainst_.mm
Port to Xcode 4.6.3: newer versions of Xcode fail.
[uikittools.git] / extrainst_.mm
index 2554c0e3f3db3710ef0066214bef7320405445bf..7c11540fd9dbbecd84d8e1a682e60fc7fefbee68 100644 (file)
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <unistd.h>
+#include <dlfcn.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <string.h>
+#include <mach-o/loader.h>
 
 #include "csstore.hpp"
 
@@ -99,24 +104,30 @@ bool FinishCydia(const char *finish) {
 }
 
 void FixCache(NSString *home, NSString *plist) {
-    printf("attempting to fix weather app issue:\n");
+    printf("attempting to fix weather app issue, please wait...\n");
 
     DeleteCSStores([home UTF8String]);
     unlink([plist UTF8String]);
 
-    system("launchctl stop com.apple.mobile.installd");
-    system("launchctl start com.apple.mobile.installd");
-
-    printf("waiting for application/icon cache rebuild...\n");
-    printf("this will timeout (harmlessly) after 90 seconds\n");
-
-    for (unsigned i(0); i != 90; ++i) {
-        if (i != 0 && (i % 10) == 0)
-            printf("after %i seconds, still waiting for rebuild...\n", i);
-        if ([[NSMutableDictionary dictionaryWithContentsOfFile: plist] objectForKey: @"User"] != nil)
-            break;
-        sleep(1);
-    }
+    bool succeeded(false);
+
+    if (void *MobileInstallation$ = dlopen("/System/Library/PrivateFrameworks/MobileInstallation.framework/MobileInstallation", RTLD_GLOBAL | RTLD_LAZY)) {
+        int (*MobileInstallation$_MobileInstallationRebuildMap)(CFBooleanRef, CFBooleanRef, CFBooleanRef);
+        MobileInstallation$_MobileInstallationRebuildMap = reinterpret_cast<int (*)(CFBooleanRef, CFBooleanRef, CFBooleanRef)>(dlsym(MobileInstallation$, "_MobileInstallationRebuildMap"));
+        if (MobileInstallation$_MobileInstallationRebuildMap != NULL) {
+            if (int error = MobileInstallation$_MobileInstallationRebuildMap(kCFBooleanTrue, kCFBooleanTrue, kCFBooleanTrue))
+                printf("failed to rebuild cache (but we gave it a good try); error #%d\n", error);
+            else {
+                printf("successfully rebuilt application information cache.\n");
+                succeeded = true;
+            }
+        } else
+            printf("unable to find _MobileInstallationRebuildMap symbol.\n");
+    } else
+        printf("unable to load MobileInstallation library.\n");
+
+    if (!succeeded)
+        printf("this is not a problem: it will be regenerated as the device boots\n");
 
     if (!FinishCydia("reboot"))
         printf("you must reboot to finalize your cache.\n");
@@ -130,7 +141,7 @@ int main(int argc, const char *argv[]) {
 
     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 
-    if (kCFCoreFoundationVersionNumber >= 700) { // XXX: iOS 6.x
+    if (kCFCoreFoundationVersionNumber >= 700 && kCFCoreFoundationVersionNumber < 800) { // XXX: iOS 6.x
         NSString *home(@"/var/mobile");
         NSString *plist([NSString stringWithFormat:@"%@/Library/Caches/com.apple.mobile.installation.plist", home]);
         NSDictionary *cache([NSDictionary dictionaryWithContentsOfFile:plist]);