123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775 |
- #define ARM
- #include <objc/runtime.h>
- #include <libgen.h>
- #include <dlfcn.h>
- #include <CoreFoundation/CoreFoundation.h>
- #ifdef ARM
- #include <Foundation/Foundation.h> // NSObject
- #endif
- @interface LSApplicationWorkspaceRemoteObserver : NSObject
- -(id)localObservers;
- @end
- @interface LSApplicationWorkspace : NSObject
- + (id) defaultWorkspace;
- @property (readonly) LSApplicationWorkspaceRemoteObserver * remoteObserver;
- - (BOOL) _LSPrivateSyncWithMobileInstallation;
- @end
- @interface PBAppDepot : NSObject
- + (id)sharedInstance;
- @property(retain, nonatomic) NSMutableDictionary *internalAppState;
- - (id)_addAppStateForIdentifier:(id)arg1;
- - (void)_save;
- - (void)_setNeedsNotifyAppStateDidChange;
- @end
- //#import "KBHelperClass.h"
- //
- // LSDTrip: A simple tool to demonstrate LaunchServices in OS X *and* iOS
- // -------
- //
- // Jonathan Levin, http://NeWOSXBook.com - @Morpheus______/@TechnoloGeeks
- //
- // License: free, but if you GitHub it or mod it, at least leave a mention.
- // And maybe get the book when it's finally out :-)
- //
- // Compile: gcc ls.m -o lsdtrip -lobjc -framework Foundation
- // or
- // gcc-iphone -DARM ls.m -o lsdtrip -lobjc -framework Foundation -framework MobileCoreServices
- //
- // (that "MobileCoreServices" is required for the dlopen(3) to work)
- //
- //
- // To run:
- // Usage: ls [apps|plugins|publicurls|privateurls] [-v]
- // whohas _url_
- // types
- // dump <<-- Try this
- //
- // Explanation:
- //
- // Shows what are (IMHO) the most useful of the LaunchServices APIs, as exported by
- // [Mobile]CoreServices. In iOS most of the good stuff isn't exported (t), instead wrapped
- // by LSApplicationWorkSpace, LSApplicationProxy, and friends. Even though the straight LS
- // and _LS calls are much nicer, I chose to use objective-C here in order to maintain
- // write-once-run-everywhere, and demonstrate yet again just how OS X and iOS really are
- // so similar.
- //
- // How this works:
- //
- // Over rather nice XPC to lsd (10.11/9.0) and friends. Full explanation in MOXiI 2.
- // (Chapter 5, "Promenade, A Tour of the OS X and iOS Frameworks", to be exact, where
- // many more "private" frameworks are exposed). But since I'm running behind with it,
- // I thought people would appreciate a hands-on preview :-) This is just one of the many
- // open source examples I have planned.
- //
- // PLEASE BE PATIENT. This should give you an idea of why MOXiI is delayed. At least I try
- // to keep everyone updated and drop examples along the way. And there's plenty more where
- // this came from. Just wait.
- //
- //
- // Improvements:
- //
- // - Can be made into pure C (i.e. not objective-C, .m), but that would make
- // the already ugly [] syntax even worse..
- //
- // - There's a whole undocumented side to LaunchServices (even as an allegedly
- // "public" framework that it is) one can add here. And I left the other
- // methods out in an #if 0 block, for future use.
- //
- // - The UUIDs aren't actually CFUUIDs. They're some $%#$%#$ NS...UUID, which
- // isn't compatible, so the UUIDs come with some 0s at the end. Meh.
- //
- // Ok. Let's begin:
- // My own prototypes and globals:
- CFStringRef dumpApp (NSObject *AppRef, int Verbose) ;
- NSObject * workspace; // Intentionally void * so as to NOT involve @interface files
- // OS X and iOS APIs are virtually identical, but the framework name is different
- #ifdef ARM
- #define CORE_SERVICE_FRAMEWORK "/System/Library/Frameworks/MobileCoreServices.framework/MobileCoreServices"
- #else
- #define CORE_SERVICE_FRAMEWORK "/System/Library/Frameworks/CoreServices.framework/CoreServices"
- #endif
- CFStringRef
- serializeCFArrayToCFString (CFArrayRef Array, CFStringRef Delimiter)
- {
-
- if (!Array) { return (CFSTR("(null)"));}
- CFMutableStringRef returned = CFStringCreateMutable(kCFAllocatorDefault, // CFAllocatorRef alloc,
- 4096); //CFIndex maxLength);
-
-
- int len = CFArrayGetCount(Array);
- int i = 0;
- for (i = 0; i < len ; i++)
-
- {
- CFTypeRef val = (CFTypeRef) CFArrayGetValueAtIndex(Array, i);
-
- if (i > 0) CFStringAppend(returned, Delimiter);
-
- // UGLY, I know. But PoC, people. PoC
- if (CFGetTypeID(val) == CFStringGetTypeID()) CFStringAppend(returned, val);
-
- else
- if (CFGetTypeID(val) == CFUUIDGetTypeID()){
- CFStringRef UUID = CFUUIDCreateString(kCFAllocatorDefault, val);
- CFStringAppend(returned, UUID);
-
- }
- else {
- CFStringAppend(returned, dumpApp (val, 0));
- };
- }
-
-
- return (returned);
-
-
- } // serializeCFArrayToCFstring
- CFStringRef
- dumpApp (NSObject *AppRef, int Verbose)
- {
- // App is an LSApplicationProxy object
-
- CFStringRef appID = (CFStringRef) [AppRef performSelector:@selector( applicationIdentifier)];
- CFStringRef appName = (CFStringRef)[AppRef performSelector:@selector(localizedName)];
-
- if (!appName) { appName = CFSTR("Not Set");}
- CFMutableStringRef out = CFStringCreateMutable(kCFAllocatorDefault, // CFAllocatorRef alloc,
- 4096); //CFIndex maxLength);
- CFStringAppendFormat(out, // CFMutableStringRef theString,
- NULL, // CFDictionaryRef formatOptions,
- CFSTR("\t%@ (%@)\n"),
- appName, appID);
-
-
- #if 0
- // Can also use objective-C to enumerate ivars..
- unsigned int ivarCount;
- Ivar *ivars = class_copyIvarList([AppRef class], &ivarCount);
-
- int i = 0;
- for (i = 0; i < ivarCount; i++)
- {
- fprintf(stderr,"\t%s: \n" , ivar_getName(ivars[i]));
- // etc.
- }
- #endif
- if (Verbose)
- {
- // Dump more
-
- CFStringAppendFormat(out, // CFMutableStringRef theString,
- NULL, // CFDictionaryRef formatOptions,
- CFSTR("\t\tExecutable: %@\n"),
- [AppRef performSelector:@selector(bundleExecutable)]);
-
- #ifdef ARM
- // Set on iOS. Can also use versionIdentifier here, but that requires working back from the
- // number to a version string (which LaunchServices lets you do with
- // LSVersionNumberCopyStringRepresentation/LSVersionNumberGetXXX()
- // But why bother when you have a short version string..
- CFStringAppendFormat(out, // CFMutableStringRef theString,
- NULL, // CFDictionaryRef formatOptions,
- CFSTR("\t\tVersion: %@\n"),
- (CFStringRef)[AppRef performSelector:@selector(shortVersionString)]);
-
- #endif
-
- // This is apparently unset..
- CFStringAppendFormat(out, // CFMutableStringRef theString,
- NULL, // CFDictionaryRef formatOptions,
- CFSTR("\t\tVendor Name: %@\n"),
- (CFStringRef)[AppRef performSelector:@selector(vendorName)]);
-
-
-
- CFStringAppendFormat(out, // CFMutableStringRef theString,
- NULL, // CFDictionaryRef formatOptions,
- CFSTR("\t\tMach-O UUIDs: %@\n"),
- serializeCFArrayToCFString((CFArrayRef)[AppRef performSelector:@selector(machOUUIDs)], CFSTR(",")));
-
-
- CFStringAppendFormat(out, // CFMutableStringRef theString,
- NULL, // CFDictionaryRef formatOptions,
- CFSTR("\t\tDisk Usage (Static): %@\n"),
- (CFStringRef)[AppRef performSelector:@selector(staticDiskUsage)]);
-
-
- #if 0
- // This apparently doesn't work in 9.2 anymore. Not sure about this..
- CFStringAppendFormat(out, // CFMutableStringRef theString,
- NULL, // CFDictionaryRef formatOptions,
- CFSTR("\t\tDisk Usage (Dynamic): %@\n"),
- (CFStringRef)[AppRef performSelector:@selector(dynamicDiskUsage)]);
-
- #endif
-
- CFArrayRef UIBackgroundModes = (CFArrayRef) [AppRef performSelector: @selector(UIBackgroundModes)];
-
-
- // This is a CFArray
- if (!CFArrayGetCount(UIBackgroundModes)) {
- CFStringAppend (out,CFSTR("\t\tno BackgroundModes"));
- }
-
- else
- CFStringAppendFormat(out, // CFMutableStringRef theString,
- NULL, // CFDictionaryRef formatOptions,
- CFSTR("\t\t BackgroundModes: %@"),
- serializeCFArrayToCFString((CFArrayRef)UIBackgroundModes, CFSTR(",")));
-
- CFStringAppend(out, CFSTR("\n"));
-
- #ifdef ARM
- // Only on iOS
- CFStringAppendFormat(out, // CFMutableStringRef theString,
- NULL, // CFDictionaryRef formatOptions,
- CFSTR("\t\tApplication DSID: %@\n"),
- (CFStringRef)[AppRef performSelector:@selector(applicationDSID)]);
-
-
-
- CFStringAppendFormat(out, // CFMutableStringRef theString,
- NULL, // CFDictionaryRef formatOptions,
- CFSTR("\t\tPurchaser DSID: %@\n"),
- (CFStringRef)[AppRef performSelector:@selector(purchaserDSID)]);
-
-
-
- CFStringAppendFormat(out, // CFMutableStringRef theString,
- NULL, // CFDictionaryRef formatOptions,
- CFSTR("\t\tDownloader DSID: %@\n"),
- (CFStringRef)[AppRef performSelector:@selector(downloaderDSID)]);
- #endif
-
-
- #if 0
- uint64_t modTime = (uint64_t)([AppRef performSelector:@selector( bundleModTime)]);
- fprintf(stderr, "\t\tBundle Mod Time: %llu\n", modTime);
- #endif
-
-
- int cont = (int)([AppRef performSelector:@selector( isContainerized)]);
- int restricted = (int)([AppRef performSelector:@selector( isRestricted)]);
-
- CFStringAppendFormat(out,
- NULL,
- CFSTR("\t\tContainerized: %@\n\t\tRestricted: %@\n"),
- (cont ? CFSTR("YES (q.v. App-Store Receipt URL for container)") : CFSTR("NO")),
- (restricted ? CFSTR("YES") : CFSTR("NO")));
-
-
-
- CFStringAppendFormat(out, // CFMutableStringRef theString,
- NULL, // CFDictionaryRef formatOptions,
- CFSTR("\t\tApp Store Receipt URL: %@\n"),
- (CFStringRef)[AppRef performSelector:@selector( appStoreReceiptURL)]);
-
-
- // These are from LSBundleProxy, which is the parent of LSApplicationProxy
- CFStringAppendFormat(out, // CFMutableStringRef theString,
- NULL, // CFDictionaryRef formatOptions,
- CFSTR("\t\tContainer URL: %@\n"),
- [AppRef performSelector:@selector(containerURL)]);
-
- CFDictionaryRef entitlements = (CFDictionaryRef) [AppRef performSelector:@selector(entitlements)];
-
- if (entitlements && CFDictionaryGetCount(entitlements) )
- {
-
- CFDataRef xml = CFPropertyListCreateXMLData(kCFAllocatorDefault,
- (CFPropertyListRef)entitlements);
-
- CFStringRef xmlAsString = CFStringCreateFromExternalRepresentation(NULL, xml, kCFStringEncodingUTF8);
-
- if (xmlAsString) {
- CFStringAppendFormat(out, // CFMutableStringRef theString,
- NULL, // CFDictionaryRef formatOptions,
- CFSTR("\t\tEntitlements:\n-----\n %@\n-----\n"),
- xmlAsString);
-
- }
- else { CFStringAppend (out, CFSTR("\t\tEntitlements: Internal error\n"));}
-
-
- } // entitlements
- else
- CFStringAppend(out,CFSTR("\t\tEntitlements: None\n"));
-
- } // Verbose
-
- return (out);
- }
- /*
- *
- Soooo much more, courtesy of JTool:
-
- -[LSApplicationProxy applicationIdentifier]:
- -[LSApplicationProxy roleIdentifier]:
- -[LSApplicationProxy bundleModTime]:
- -[LSApplicationProxy registeredDate]:
- -[LSApplicationProxy deviceFamily]:
- -[LSApplicationProxy minimumSystemVersion]:
- -[LSApplicationProxy sdkVersion]:
- -[LSApplicationProxy applicationType]:
- -[LSApplicationProxy itemName]:
- -[LSApplicationProxy sourceAppIdentifier]:
- -[LSApplicationProxy companionApplicationIdentifier]:
- -[LSApplicationProxy applicationVariant]:
- -[LSApplicationProxy storeCohortMetadata]:
- -[LSApplicationProxy shortVersionString]:
- -[LSApplicationProxy preferredArchitecture]:
- -[LSApplicationProxy familyID]:
- -[LSApplicationProxy groupContainers]:
- -[LSApplicationProxy directionsModes]:
- -[LSApplicationProxy UIBackgroundModes]:
- -[LSApplicationProxy audioComponents]:
- -[LSApplicationProxy externalAccessoryProtocols]:
- -[LSApplicationProxy VPNPlugins]:
- -[LSApplicationProxy plugInKitPlugins]:
- -[LSApplicationProxy appTags]:
- -[LSApplicationProxy requiredDeviceCapabilities]:
- -[LSApplicationProxy deviceIdentifierForVendor]:
- -[LSApplicationProxy ODRDiskUsage]:
- -[LSApplicationProxy storeFront]:
- -[LSApplicationProxy externalVersionIdentifier]:
- -[LSApplicationProxy betaExternalVersionIdentifier]:
- -[LSApplicationProxy appStoreReceiptURL]:
- -[LSApplicationProxy installProgress]:
- -[LSApplicationProxy installProgressSync]:
- -[LSApplicationProxy resourcesDirectoryURL]:
- -[LSApplicationProxy privateDocumentIconNames]:
- -[LSApplicationProxy setPrivateDocumentIconNames:]:
- -[LSApplicationProxy privateIconsDictionary]:
- -[LSApplicationProxy privateDocumentIconAllowOverride]:
- -[LSApplicationProxy setPrivateDocumentIconAllowOverride:]:
- -[LSApplicationProxy iconDataForVariant:]:
- -[LSApplicationProxy privateDocumentTypeOwner]:
- -[LSApplicationProxy setPrivateDocumentTypeOwner:]:
- -[LSApplicationProxy localizedName]:
- -[LSApplicationProxy localizedShortName]:
- -[LSApplicationProxy localizedNameForContext:]:
- -[LSApplicationProxy iconIsPrerendered]:
- -[LSApplicationProxy fileSharingEnabled]:
- -[LSApplicationProxy profileValidated]:
- -[LSApplicationProxy isAdHocCodeSigned]:
- -[LSApplicationProxy isPlaceholder]:
- -[LSApplicationProxy isAppUpdate]:
- -[LSApplicationProxy isNewsstandApp]:
- -[LSApplicationProxy isRestricted]:
- -[LSApplicationProxy supportsAudiobooks]:
- -[LSApplicationProxy supportsExternallyPlayableContent]:
- -[LSApplicationProxy supportsOpenInPlace]:
- -[LSApplicationProxy hasSettingsBundle]:
- -[LSApplicationProxy isInstalled]:
- -[LSApplicationProxy isWhitelisted]:
- -[LSApplicationProxy isBetaApp]:
- -[LSApplicationProxy isPurchasedReDownload]:
- -[LSApplicationProxy isWatchKitApp]:
- -[LSApplicationProxy hasMIDBasedSINF]:
- -[LSApplicationProxy missingRequiredSINF]:
- -[LSApplicationProxy isEqual:]:
- -[LSApplicationProxy hash]:
- -[LSApplicationProxy description]:
- -[LSApplicationProxy iconStyleDomain]:
- -[LSApplicationProxy userActivityStringForAdvertisementData:]:
- -[LSApplicationProxy populateNotificationData]:
- -[LSApplicationProxy itemID]:
- -[LSApplicationProxy installType]:
- -[LSApplicationProxy originalInstallType]:
- -[LSApplicationProxy groupIdentifiers]:
- -[LSApplicationProxy teamID]:
- -[LSApplicationProxy isContainerized]:
- */
- void
- dumpURL (CFStringRef URL, int Verbose)
- {
-
- CFMutableStringRef out = CFStringCreateMutable(kCFAllocatorDefault, // CFAllocatorRef alloc,
- 4096); //CFIndex maxLength);
-
- CFStringAppend(out, URL);
- if (Verbose) {
- CFArrayRef appsForURL = (CFArrayRef) [workspace performSelector:@selector(applicationsAvailableForHandlingURLScheme:) withObject:(id)URL];
-
- // This is a CFArray
- if (CFGetTypeID(appsForURL) != CFArrayGetTypeID())
- {
- fprintf(stderr, "Was expecting a CFArray of Apps!\n");
- exit(2);
- }
-
- if (!CFArrayGetCount (appsForURL)) CFStringAppend(out,CFSTR(" - Not claimed by anyone"));
- else {
-
- CFStringRef apps = serializeCFArrayToCFString (appsForURL, CFSTR("\n\t\t\t"));
-
- CFStringAppend (out, apps);
- CFRelease (apps);
- }
- }
-
- CFShow(out);
- CFRelease(out);
- }
- void
- dumpPlugin (NSObject *PluginRef, int Verbose)
- {
-
- CFStringRef pluginName = (CFStringRef) [PluginRef performSelector:@selector( localizedName)];
- CFStringRef pluginID = (CFStringRef) [PluginRef performSelector:@selector( pluginIdentifier)];
- CFUUIDRef pluginUUID = (CFUUIDRef)[PluginRef performSelector:@selector(pluginUUID)];
-
- CFStringRef out = CFStringCreateWithFormat(kCFAllocatorDefault,
- NULL, CFSTR("\t%@ (%@) - %@"),
- pluginName,pluginID, CFUUIDCreateString(kCFAllocatorDefault, pluginUUID));
-
- CFShow(out);
-
-
- } // end Dump
- int
- main (int argc, char **argv)
- {
-
- int verbose = 0;
-
- // So - why dup? because CFShow(), which I use extensively, write to stderr.
- // And I really CANNOT stand the whole CFStringToCstr $%#$%#$ just to get a stupid
- // printout! So instead, I save stderr, and then reopen stderr to stdout. This
- // way, the output can be grep(1)-ed easily.
-
- dup2(2,3);
- dup2(1,2);
-
-
- if (argc < 2)
- {
-
- fprintf(stderr, "Usage: %s [apps|plugins|publicurls|privateurls] [-v]\n", basename(argv[0]));
- fprintf(stderr, " app _bundle_id_ (implies -v for this app)\n");
- #ifdef ARM
- fprintf(stderr, " launch _bundle_id_\n");
- #endif
- fprintf(stderr, " whohas _url_ \n");
- fprintf(stderr, " types\n");
- fprintf(stderr, " dump\n");
- exit(0);
- }
-
- if (argv[2] && strcmp(argv[2], "-v")==0) verbose++;
-
- // Getting the LS* classes and functions we need here:
- // ---------------------------------------------------
- Class LSApplicationWorkspace_class = objc_getClass("LSApplicationWorkspace");
- if (!LSApplicationWorkspace_class) {fprintf(stderr,"Unable to get Workspace class\n"); exit(1);}
- workspace = [LSApplicationWorkspace_class performSelector:@selector (defaultWorkspace)];
- if (!workspace) {fprintf(stderr,"Unable to get Workspace\n"); exit(2);}
-
- NSLog(@"workspace: %@", workspace);
- LSApplicationWorkspaceRemoteObserver *observer = [workspace remoteObserver];
- NSArray *localObservers = [observer localObservers];
- NSLog(@"local observers: %@", localObservers);
-
-
- // KBHelperClass *helperClass = [KBHelperClass new];
- //[helperClass doMagic];
-
- void *CS_handle = dlopen (CORE_SERVICE_FRAMEWORK, RTLD_NOW);
- if (!CS_handle) { fprintf(stderr,"Can't find %s!\n", CORE_SERVICE_FRAMEWORK); exit(2); };
-
-
- if (strncmp(argv[1], "app",3) == 0)
- {
-
- CFStringRef wantedBundleID = NULL;
-
- if (strcmp(argv[1], "apps")) // that is, not all apps
- {
- // expecting a bundle identifier here
-
- if (!argv[2]) { fprintf(stderr,"app option requires a specific bundle id. Try 'apps' to get a list\n");
- exit(5); }
-
- wantedBundleID = CFStringCreateWithCString(kCFAllocatorDefault, // CFAllocatorRef alloc,
- argv[2], // const char *cStr,
- kCFStringEncodingUTF8); //CFStringEncoding encoding);
- }
-
- CFArrayRef apps = (CFArrayRef) [workspace performSelector:@selector(allApplications)];
- // This is a CFArray
- if (CFGetTypeID(apps) != CFArrayGetTypeID())
- {
- fprintf(stderr, "Was expecting a CFArray of Apps!\n");
- exit(2);
- }
-
- int len = CFArrayGetCount(apps);
- int i = 0;
- for (i = 0; i < len ; i++)
- {
- CFTypeRef app = CFArrayGetValueAtIndex(apps,i);
-
- // Got app: Dump if want all, or if matches id.
- // I'm sure there's some Workspace method I missed to get an app by bundle ID, instead
- // of iterating over all of them..
-
- CFStringRef appID = (CFStringRef) [(id)app performSelector:@selector(applicationIdentifier)];
-
- if (appID && wantedBundleID)
- {
- if (CFEqual(appID, wantedBundleID))
- {
- CFStringRef dump = dumpApp(app, 1);
- CFShow(dump);
- CFRelease(dump);
- exit(0); // only one match here.
- }
- }
- else
- {
- CFStringRef dump = dumpApp(app, verbose);
- CFShow(dump);
- CFRelease(dump);
-
-
- }
- }
-
- if ( wantedBundleID) {
- fprintf(stderr,"Application with Bundle ID %s not found. Try '%s apps' first, and remember case-sensitivity\n",
- argv[2], argv[0]);
- exit(2);
- }
-
- exit(0);
- }
-
- if (strcmp(argv[1], "publicurls") == 0)
- {
- CFArrayRef puburls = (CFArrayRef) [workspace performSelector:@selector(publicURLSchemes)];
-
-
- // This is a CFArray
- if (CFGetTypeID(puburls) != CFArrayGetTypeID())
- {
- fprintf(stderr, "Was expecting a CFArray of publicURLSchemes!\n");
- exit(2);
- }
-
- int len = CFArrayGetCount(puburls);
- int i = 0;
- for (i = 0; i < len ; i++)
- {
- CFStringRef url = CFArrayGetValueAtIndex(puburls,i);
- dumpURL(url, verbose);
-
-
-
- }
- exit(0);
-
- }
-
- if (strcmp(argv[1], "privateurls") == 0)
- {
- CFArrayRef (privurls) = (CFArrayRef) [workspace performSelector:@selector(privateURLSchemes)];
- // This is a CFArray
- if (CFGetTypeID(privurls) != CFArrayGetTypeID())
- {
- fprintf(stderr, "Was expecting a CFArray of privateURLSchemes!\n");
- exit(2);
- }
-
- int len = CFArrayGetCount(privurls);
- int i = 0;
- for (i = 0; i < len ; i++)
- {
- CFStringRef url = CFArrayGetValueAtIndex(privurls,i);
- dumpURL(url, verbose);
-
-
-
- }
- exit(0);
-
- }
-
-
- if (strcmp(argv[1], "plugins") == 0)
- {
- CFArrayRef plugins = (CFArrayRef) [workspace performSelector:@selector(installedPlugins)];
- // This, too, is a CFArray
- if (CFGetTypeID(plugins) != CFArrayGetTypeID())
- {
- fprintf(stderr, "Was expecting a CFArray of plugins!\n");
- exit(2);
- }
-
- int len = CFArrayGetCount(plugins);
- int i = 0;
- for (i = 0; i < len ; i++)
- {
- CFTypeRef plugin = CFArrayGetValueAtIndex(plugins,i);
- dumpPlugin(plugin, verbose);
-
-
-
- }
- exit(0);
- }
-
- if (strcmp(argv[1], "types") == 0)
- {
- // I resort to dlopen/dlsym here to make linking simpler. You don't have to.
-
- typedef CFArrayRef (*UTCopyDeclaredTypeIdentifiersFunc)(void);
-
- UTCopyDeclaredTypeIdentifiersFunc UTCopyDeclaredTypeIdentifiers
- = dlsym (CS_handle, "_UTCopyDeclaredTypeIdentifiers");
-
- CFArrayRef utis = UTCopyDeclaredTypeIdentifiers();
-
- // As usual, this is an array..
- int len = CFArrayGetCount(utis);
- int i = 0;
- for (i = 0; i < len ; i++)
- {
- // Seriously, AAPL - couldn't you find a better acronym?
- CFTypeRef uti = CFArrayGetValueAtIndex(utis,i);
- CFShow(uti);
-
-
-
- }
- exit(0);
-
-
-
- }
-
- if (strcmp(argv[1], "whohas") == 0)
- {
-
- if (!argv[2]) {
- fprintf(stderr,"whohas: Option requires an URL Scheme or UTI as an argument!\n");
- exit(3);
- }
-
-
-
- CFStringRef url = CFStringCreateWithCString(kCFAllocatorDefault, // CFAllocatorRef alloc,
- argv[2], // const char *cStr,
- kCFStringEncodingUTF8); //CFStringEncoding encoding);
-
-
-
- dumpURL(url,1);
-
-
- exit(0);
- }
-
-
-
- #if 0
- // ignore this part for now
- if (strcmp(argv[1],"claims") == 0)
- {
-
- typedef CFStringRef (*LSCopyClaimedActivityIdentifiersAndDomainsFunc)(CFStringRef, CFStringRef);
-
- LSCopyClaimedActivityIdentifiersAndDomainsFunc
- LSCopyClaimedActivityIdentifiersAndDomains = dlsym (CS_handle, "_LSCopyClaimedActivityIdentifiersAndDomains");
-
- if (!LSCopyClaimedActivityIdentifiersAndDomains )
- {
- fprintf(stderr,"Unable to find LSCopyClaimedActivityIdentifiersAndDomains ");
- exit(3);
- }
-
- CFStringRef result = LSCopyClaimedActivityIdentifiersAndDomains (NULL, NULL);
- CFShow(result);
- exit(0);
-
-
- }
- #endif
-
-
-
- if (strcmp(argv[1],"launch") == 0)
- {
-
-
- if (!argv[2]) {
- fprintf(stderr,"launch: Option requires an argument!\n"); exit(3);
- }
- CFStringRef bundleID = CFStringCreateWithCString(kCFAllocatorDefault, // CFAllocatorRef alloc,
- argv[2], // const char *cStr,
- kCFStringEncodingUTF8); //CFStringEncoding encoding);
- int t = (int) [workspace performSelector:@selector(openApplicationWithBundleID:) withObject:(id) bundleID ];
-
- fprintf(stderr, "%s %s\n",
- t ? "Launched" : "Unable to launch",
- argv[2]);
-
- exit(0);
-
- }
-
- // And this is the real fun part:
- //
- // The little known "lsregister" utility in OS X is closed source, and un-man(1)ned,
- // But one of its coolest features is "dump" - to dump the LaunchServices Database.
- // Turns out this is a *single* line of code. And guess what -- it works on iOS too :-)
- //
- if (strcmp(argv[1], "dump") == 0)
- {
-
- typedef void (*LSDisplayDataFunc)(char *);
- LSDisplayDataFunc LSDisplayData;
-
- // If you want to get the raw format of the file, you can dump with this, instead:
- //extern _LSDisplayRawStoreData(char *, int);
- //_LSDisplayRawStoreData("/var/mobile/Library/Caches/com.apple.LaunchServices-134.csstore", (void *) 0xff);
-
-
- LSDisplayData = dlsym (CS_handle, "_LSDisplayData");
-
- if (!LSDisplayData) { fprintf(stderr, "Can't find LSDisplayData! Has Apple removed it by now? :-P"); exit(1);}
-
- // The argument expected here is the name of the CoreServices (LaunchServices)
- // DataStore - in iOS "/var/mobile/Library/Caches/com.apple.LaunchServices-###.csstore"
- // but turns out NULL works on both OS X and iOS!
-
- LSDisplayData("/private/var/containers/Data/System/97D6E4BA-C0BF-408B-AF63-1836844381AE/Library/Caches/com.apple.LaunchServices-175-v2.csstore");
- exit(0);
-
- }
-
- }
|