1/* 2 * Copyright (c) 2014 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24#include "application.h" 25 26#include <libproc.h> 27#include <CoreFoundation/CFBundlePriv.h> 28#include <Security/Security.h> 29 30dispatch_queue_t __ApplicationGetQueue( void ) 31{ 32 static dispatch_once_t once; 33 static dispatch_queue_t queue; 34 35 dispatch_once( &once, ^ 36 { 37 queue = dispatch_queue_create( 0, 0 ); 38 } ); 39 40 return queue; 41} 42 43CFBundleRef _ApplicationCopyBundle( pid_t processID ) 44{ 45 __block CFBundleRef bundle = 0; 46 47 dispatch_sync( __ApplicationGetQueue( ), ^ 48 { 49 int length; 50 uint8_t path[ PROC_PIDPATHINFO_MAXSIZE ]; 51 52 length = proc_pidpath( processID, path, PROC_PIDPATHINFO_MAXSIZE ); 53 54 if ( length ) 55 { 56 CFURLRef url; 57 58 url = CFURLCreateFromFileSystemRepresentation( kCFAllocatorDefault, path, length, TRUE ); 59 60 if ( url ) 61 { 62 bundle = _CFBundleCreateWithExecutableURLIfMightBeBundle( kCFAllocatorDefault, url ); 63 64 CFRelease( url ); 65 } 66 } 67 } ); 68 69 return bundle; 70} 71 72CFStringRef _ApplicationCopyIdentifier( pid_t processID ) 73{ 74 __block CFStringRef identifier = 0; 75 76 dispatch_sync( __ApplicationGetQueue( ), ^ 77 { 78 CFMutableDictionaryRef attributes; 79 80 attributes = CFDictionaryCreateMutable( kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks ); 81 82 if ( attributes ) 83 { 84 CFNumberRef number; 85 86 number = CFNumberCreate( kCFAllocatorDefault, kCFNumberIntType, &processID ); 87 88 if ( number ) 89 { 90 SecCodeRef code = 0; 91 92 CFDictionarySetValue( attributes, kSecGuestAttributePid, number ); 93 94 SecCodeCopyGuestWithAttributes( 0, attributes, kSecCSDefaultFlags, &code ); 95 96 if ( code ) 97 { 98 CFDictionaryRef information = 0; 99 100 SecCodeCopySigningInformation( code, kSecCSDefaultFlags, &information ); 101 102 if ( information ) 103 { 104 identifier = CFDictionaryGetValue( information, kSecCodeInfoIdentifier ); 105 106 if ( identifier ) 107 { 108 CFRetain( identifier ); 109 } 110 111 CFRelease( information ); 112 } 113 114 CFRelease( code ); 115 } 116 117 CFRelease( number ); 118 } 119 120 CFRelease( attributes ); 121 } 122 } ); 123 124 return identifier; 125} 126