#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"
}
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");
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]);