예제 #1
0
// Opens a session on the iPod. This should be called before starting any
// operation to ensure the iPod hasn't been disconnected since the last time,
// or simply to initialize the first connection if it hasn't been done before.
//
// Returns:
//		IPOD_ERR_OK				when successful
//		IPOD_IPOD_NOT_FOUND		if no iPod is connected to any USB port
//		IPOD_COULD_NOT_CONNECT	if the connection could not be established
//
t_iPodError CiPoTApi::OpenSession()
{
	t_MachError ret;
	int timeout;

	CheckConnection();
	if (m_ApiState == API_STATE_AVAILABLE)
		// Session is already open
		return IPOD_ERR_OK;
	// Checks if iPod connected
	for (timeout = 0; (timeout < 200) && (m_iPodState != IPOD_STATE_CONNECTED); timeout++)
		Sleep(10);
	if (m_iPodState != IPOD_STATE_CONNECTED)
		return IPOD_IPOD_NOT_FOUND;
	// Opens a session for this instance
	m_pDev = (t_AMDevice *)m_iPodDev;
	if (AMDeviceStartService(m_pDev, m_iPodAFCName, &m_iPodAFC, NULL)) {
		// Not jailbroken, tries to connect to the standard name
		m_iPodAFCName = AMSVC_AFC;
		ret = AMDeviceStartService(m_pDev, m_iPodAFCName, &m_iPodAFC, NULL);
		if (ret)
			return IPOD_COULD_NOT_CONNECT;
	}
	lstrcpyn(m_Serial, m_pDev->serial, sizeof(m_Serial));
	if (AFCConnectionOpen(m_iPodAFC, 0, &m_iPodConnection))
		return IPOD_COULD_NOT_CONNECT;
	m_ApiState = API_STATE_AVAILABLE;
	m_ConnectionID = m_GlobalConnectionID;
	return IPOD_ERR_OK;
}
예제 #2
0
kern_return_t test_apple_AFCOperationCreateGetConnectionInfo(struct am_device *apple, CFTypeRef *response) {
	kern_return_t apple_return = kAMDUndefinedError;
	kern_return_t result = AMDeviceConnect(apple);
	if (SDM_MD_CallSuccessful(result)) {
		result = AMDeviceStartSession(apple);
		if (SDM_MD_CallSuccessful(result)) {
			service_conn_t test_apple_afc_conn;
			result = AMDeviceStartService(apple, CFSTR(AMSVC_AFC), &test_apple_afc_conn, NULL);
			if (SDM_MD_CallSuccessful(result)) {
				struct afc_connection *afc = NULL;
				result = AFCConnectionOpen(test_apple_afc_conn, 0, &afc);
				if (afc) {
					afc_operation conn_info = AFCOperationCreateGetConnectionInfo(kCFAllocatorDefault, NULL);
					result = AFCConnectionProcessOperation(afc, conn_info, 0);
					if (SDM_MD_CallSuccessful(result)) {
						CFTypeRef test = AFCOperationGetResultObject(conn_info);
						if (test) {
							*response = test;
							apple_return = kAMDSuccess;
						}
					}
					AFCConnectionClose(afc);
				}
			}
			AMDeviceStopSession(apple);
		}
		AMDeviceDisconnect(apple);
	}
	return apple_return;
}
예제 #3
0
/** Connect to an iPhone device, and register callbacks.
  * Members of the iPhone struct that must be valid: dnc
  * for device notifications
  */
BOOL iPhone_Connect(iPhone *iphone)
{
    if(AMDeviceConnect(iphone->handle) == 1)
    { 
        iPhone_SetLastError("Device is in recovery mode. Must be activated with iTunes."); 
        return FALSE ; 
    }
    
    if(AMDeviceIsPaired(iphone->handle) == 0)
    { 
        iPhone_SetLastError("AMDeviceIsPaired failed."); 
        return FALSE; 
    }
    
    if(AMDeviceValidatePairing(iphone->handle) != 0)
    { 
        iPhone_SetLastError("AMDeviceValidatePairing failed."); 
        return FALSE; 
    }
    
    if(AMDeviceStartSession(iphone->handle) == 1)
    { 
        iPhone_SetLastError("AMDeviceStartSession failed."); 
        return FALSE; 
    }
    
    if(AMDeviceStartService(iphone->handle, __CFStringMakeConstantString("com.apple.afc2"), &iphone->hService, NULL) != 0)
    {
        if(AMDeviceStartService(iphone->handle, __CFStringMakeConstantString("com.apple.afc"), &iphone->hService, NULL) != 0)
            return FALSE;
    }
    
    if(AFCConnectionOpen(iphone->hService, 0, &iphone->hAFC) != 0)
    { 
        iPhone_SetLastError("AFCConnectionOpen failed."); 
        return FALSE; 
    }
    
    iphone->connected = TRUE;
    return TRUE;
}
예제 #4
0
service_conn_t start_afc_service(AMDeviceRef device) {
    AMDeviceConnect(device);
    assert(AMDeviceIsPaired(device));
    assert(AMDeviceValidatePairing(device) == 0);
    assert(AMDeviceStartSession(device) == 0);

    service_conn_t afcFd;
    assert(AMDeviceStartService(device, AMSVC_AFC, &afcFd, NULL) == 0);

    assert(AMDeviceStopSession(device) == 0);
    assert(AMDeviceDisconnect(device) == 0);
    return afcFd;
}
예제 #5
0
service_conn_t start_install_proxy_service(AMDeviceRef device) {
    AMDeviceConnect(device);
    assert(AMDeviceIsPaired(device));
    assert(AMDeviceValidatePairing(device) == 0);
    assert(AMDeviceStartSession(device) == 0);

    service_conn_t installFd;
    assert(AMDeviceStartService(device, CFSTR("com.apple.mobile.installation_proxy"), &installFd, NULL) == 0);

    assert(AMDeviceStopSession(device) == 0);
    assert(AMDeviceDisconnect(device) == 0);

    return installFd;
}
예제 #6
0
void start_remote_debug_server(AMDeviceRef device) {
    assert(AMDeviceStartService(device, CFSTR("com.apple.debugserver"), &gdbfd, NULL) == 0);

    CFSocketRef fdvendor = CFSocketCreate(NULL, AF_UNIX, 0, 0, kCFSocketAcceptCallBack, &fdvendor_callback, NULL);

    int yes = 1;
    setsockopt(CFSocketGetNative(fdvendor), SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));

    struct sockaddr_un address;
    memset(&address, 0, sizeof(address));
    address.sun_family = AF_UNIX;
    strcpy(address.sun_path, FDVENDOR_PATH);
    CFDataRef address_data = CFDataCreate(NULL, (const UInt8 *)&address, sizeof(address));

    unlink(FDVENDOR_PATH);

    CFSocketSetAddress(fdvendor, address_data);
    CFRelease(address_data);
    CFRunLoopAddSource(CFRunLoopGetMain(), CFSocketCreateRunLoopSource(NULL, fdvendor, 0), kCFRunLoopCommonModes);
}
예제 #7
0
kern_return_t test_apple_AFCConnectionCreate(struct am_device *apple) {
	kern_return_t apple_return = kAMDUndefinedError;
	kern_return_t result = AMDeviceConnect(apple);
	if (SDM_MD_CallSuccessful(result)) {
		result = AMDeviceStartSession(apple);
		if (SDM_MD_CallSuccessful(result)) {
			service_conn_t test_apple_afc_conn;
			result = AMDeviceStartService(apple, CFSTR(AMSVC_AFC), &test_apple_afc_conn, NULL);
			if (SDM_MD_CallSuccessful(result)) {
				struct afc_connection *afc = NULL;
				result = AFCConnectionOpen(test_apple_afc_conn, 0, &afc);
				if (afc) {
					apple_return = kAMDSuccess;
					AFCConnectionClose(afc);
				}
			}
			AMDeviceStopSession(apple);
		}
		AMDeviceDisconnect(apple);
	}
	return apple_return;
}
예제 #8
0
static void cb(am_device_notification_callback_info * info, void *foo)
{
	struct am_device *dev;

	if (info->msg == ADNCI_MSG_CONNECTED) {
		dev = info->dev;

		AMDeviceConnect(dev);
		assert(AMDeviceIsPaired(dev));
		assert(!AMDeviceValidatePairing(dev));
		assert(!AMDeviceStartSession(dev));

		CFStringRef product =
		    AMDeviceCopyValue(dev, 0, CFSTR("ProductVersion"));
		assert(product);
		UniChar first = CFStringGetCharacterAtIndex(product, 0);
		int epoch = first - '0';
Retry:	{}
		printf("Attempting to mount image...\n");

		service_conn_t afc_socket = 0;
		struct afc_connection *afc = NULL;
		assert(!AMDeviceStartService(dev, CFSTR("com.apple.afc"), &afc_socket, NULL));
		assert(!AFCConnectionOpen(afc_socket, 0, &afc));
		assert(!AFCDirectoryCreate(afc, "PublicStaging"));

		AFCRemovePath(afc, "PublicStaging/staging.dimage");
		qwrite(afc, real_dmg, "PublicStaging/staging.dimage");
		qwrite(afc, ddi_dmg, "PublicStaging/ddi.dimage");

		service_conn_t mim_socket1 = 0;
		service_conn_t mim_socket2 = 0;
		assert(!AMDeviceStartService(dev, CFSTR("com.apple.mobile.mobile_image_mounter"), &mim_socket1, NULL));
		assert(mim_socket1);

		CFPropertyListRef result = NULL;
		CFMutableDictionaryRef dict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
		CFDictionarySetValue(dict, CFSTR("Command"), CFSTR("MountImage"));
		CFDictionarySetValue(dict, CFSTR("ImageType"), CFSTR("Developer"));

		CFDictionarySetValue(dict, CFSTR("ImagePath"), CFSTR("/var/mobile/Media/PublicStaging/staging.dimage"));

		int fd = open(real_dmg_signature, O_RDONLY);
		assert(fd != -1);
		uint8_t sig[128];
		assert(read(fd, sig, sizeof(sig)) == sizeof(sig));
		close(fd);

		CFDictionarySetValue(dict, CFSTR("ImageSignature"), CFDataCreateWithBytesNoCopy(NULL, sig, sizeof(sig), kCFAllocatorNull));
		send_message(mim_socket1, dict);

		usleep(timesl);
		assert(!AFCRenamePath(afc, "PublicStaging/ddi.dimage", "PublicStaging/staging.dimage"));

		result = receive_message(mim_socket1);

		int len = CFDataGetLength(CFPropertyListCreateXMLData(NULL, result));
		char* bytes = CFDataGetBytePtr(CFPropertyListCreateXMLData(NULL, result));

		if(strstr(bytes, "Complete")) {
			char* the_service = "CopyIt";
			service_conn_t socket = 0;
			sleep(2);
			printf("Image mounted, running helper...\n");
			assert(!AMDeviceStartService(dev, CFStringCreateWithCStringNoCopy(NULL, the_service, kCFStringEncodingUTF8, kCFAllocatorNull),
				&socket, NULL));
			assert(!fcntl(socket, F_SETFL, O_NONBLOCK));
			assert(!fcntl(0, F_SETFL, O_NONBLOCK));
		} else {
			printf("Failed to inject image, trying again... (if it fails, try a different time), delay ... %dus\n", timesl);
			timesl += 1000;
			goto Retry;
		}

		exit(0);
	}
}
예제 #9
0
void handle_device(AMDeviceRef device) {
    if (found_device) return; // handle one device only

    CFStringRef found_device_id = AMDeviceCopyDeviceIdentifier(device);

    if (device_id != NULL) {
        if(strcmp(device_id, CFStringGetCStringPtr(found_device_id, CFStringGetSystemEncoding())) == 0) {
            found_device = true;
        } else {
            return;
        }
    } else {
        found_device = true;
    }

    CFRetain(device); // don't know if this is necessary?

    printf("[  0%%] Found device (%s), beginning install\n", CFStringGetCStringPtr(found_device_id, CFStringGetSystemEncoding()));

    AMDeviceConnect(device);
    assert(AMDeviceIsPaired(device));
    assert(AMDeviceValidatePairing(device) == 0);
    assert(AMDeviceStartSession(device) == 0);

    CFStringRef path = CFStringCreateWithCString(NULL, app_path, kCFStringEncodingASCII);
    CFURLRef relative_url = CFURLCreateWithFileSystemPath(NULL, path, kCFURLPOSIXPathStyle, false);
    CFURLRef url = CFURLCopyAbsoluteURL(relative_url);

    CFRelease(relative_url);

    service_conn_t afcFd;
    assert(AMDeviceStartService(device, CFSTR("com.apple.afc"), &afcFd, NULL) == 0);
    assert(AMDeviceStopSession(device) == 0);
    assert(AMDeviceDisconnect(device) == 0);
    assert(AMDeviceTransferApplication(afcFd, path, NULL, transfer_callback, NULL) == 0);

    close(afcFd);

    CFStringRef keys[] = { CFSTR("PackageType") };
    CFStringRef values[] = { CFSTR("Developer") };
    CFDictionaryRef options = CFDictionaryCreate(NULL, (const void **)&keys, (const void **)&values, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);

    AMDeviceConnect(device);
    assert(AMDeviceIsPaired(device));
    assert(AMDeviceValidatePairing(device) == 0);
    assert(AMDeviceStartSession(device) == 0);

    service_conn_t installFd;
    assert(AMDeviceStartService(device, CFSTR("com.apple.mobile.installation_proxy"), &installFd, NULL) == 0);

    assert(AMDeviceStopSession(device) == 0);
    assert(AMDeviceDisconnect(device) == 0);

    mach_error_t result = AMDeviceInstallApplication(installFd, path, options, install_callback, NULL);
    if (result != 0)
    {
       printf("AMDeviceInstallApplication failed: %d\n", result);
        exit(1);
    }

    close(installFd);

    CFRelease(path);
    CFRelease(options);

    printf("[100%%] Installed package %s\n", app_path);

    if (!debug) exit(0); // no debug phase

    AMDeviceConnect(device);
    assert(AMDeviceIsPaired(device));
    assert(AMDeviceValidatePairing(device) == 0);
    assert(AMDeviceStartSession(device) == 0);

    printf("------ Debug phase ------\n");

    mount_developer_image(device);      // put debugserver on the device
    start_remote_debug_server(device);  // start debugserver
    write_gdb_prep_cmds(device, url);   // dump the necessary gdb commands into a file

    CFRelease(url);

    printf("[100%%] Connecting to remote debug server\n");
    printf("-------------------------\n");

    signal(SIGHUP, gdb_ready_handler);
    signal(SIGINT, killed);
    signal(SIGTERM, killed);

    pid_t parent = getpid();
    int pid = fork();
    if (pid == 0) {
        CFStringRef path = copy_xcode_path_for(CFSTR("Platforms/iPhoneOS.platform/Developer/usr/libexec/gdb"), CFSTR("gdb-arm-apple-darwin"));
        if (path == NULL) {
            printf("[ !! ] Unable to locate GDB.\n");
            kill(parent, SIGHUP);
            exit(1);
        } else {
            CFStringRef gdb_cmd = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@ %@ %s"), path, CFSTR(GDB_SHELL), gdb_args);
 
            // Convert CFStringRef to char* for system call
            const char *char_gdb_cmd = CFStringGetCStringPtr(gdb_cmd, kCFStringEncodingMacRoman);

            system(char_gdb_cmd);      // launch gdb
        }
        kill(parent, SIGHUP);  // "No. I am your father."
        _exit(0);
    }
}
예제 #10
0
static void device_notification_callback(am_device_notification_callback_info *info, void *thing) {
	if (info->msg != ADNCI_MSG_CONNECTED) return;
	puts("Opened device connection.");
	
	am_device *dev = info->dev;
	AMDeviceConnect(dev);
	assert(AMDeviceIsPaired(dev));
	assert(AMDeviceValidatePairing(dev) == 0);
	assert(AMDeviceStartSession(dev) == 0);
		
	struct afc_connection *afc;
	service_conn_t afc_conn;
	assert(AMDeviceStartService(dev, CFSTR("com.apple.afc2"), &afc_conn, NULL) == 0);
	assert(AFCConnectionOpen(afc_conn, 0, &afc) == 0);
	
	char cachepath[63];
	const char *caches[3] = {"dyld_shared_cache_armv7s", "dyld_shared_cache_armv7", "dyld_shared_cache_armv6"};
	
	struct afc_dictionary *dict;
	unsigned int cache_index;
	char *fullpath;
	size_t cachesize;
	for (cache_index=0; cache_index<3; cache_index++) {
		strcpy(cachepath, "/System/Library/Caches/com.apple.dyld/");
		fullpath = strcat(cachepath, caches[cache_index]);
		
		if (AFCFileInfoOpen(afc, fullpath, &dict) == 0) {
			char *key, *value;
			while (1) {
				assert(AFCKeyValueRead(dict, &key, &value) == 0);
				if (key == NULL) break;
				
				if (strcmp(key, "st_size") == 0) {
					cachesize = strtol(value, NULL, 0);
					break;
				}
			}
			
			printf("Found cache %s with size %lu\n", fullpath, cachesize);
			
			assert(AFCKeyValueClose(dict) == 0);
			goto _label_hasfile;
		}
	}
	
	fprintf(stderr, "Could not find cache file.\n");
	exit(2);
	
	_label_hasfile:;
	afc_file_ref cache;
	assert(AFCFileRefOpen(afc, fullpath, 1, &cache) == 0);
	
	if (is_cwd) {
		strcat(outputfile, "/");
		strcat(outputfile, caches[cache_index]);
		
		gen_path = 1;
	}
	
	puts(outputfile);
	FILE *output = fopen(outputfile, "w");
	assert(output != NULL);
	printf("Writing cache to %s\n", outputfile);
	
	size_t total_bytes = 0;
	char buffer[65536];
	while (1) {
		unsigned int length = 65536;
		assert(AFCFileRefRead(afc, cache, buffer, &length) == 0);
		
		fwrite(buffer, sizeof(char), length, output);
		
		total_bytes += length;
		float progress = (float)total_bytes/cachesize*100;
		printf("Progress: %f%%\n\033[F\033[J", progress);
		
		if (length < sizeof(buffer)) break;
	}
	printf("Successfully wrote cache to %s\n", outputfile);
	
	assert(AFCFileRefClose(afc, cache) == 0);
	
	CFRunLoopStop(CFRunLoopGetCurrent());
}
 static int StartService(void* DeviceHandle, void** OutHandle)
 {
     int Result = AMDeviceStartService(DeviceHandle, CFSTR("com.apple.mobile.installation_proxy"), OutHandle, 0);
     return Result;
 }
 static int StartService(void* DeviceHandle, void** OutHandle)
 {
     int Result = AMDeviceStartService(DeviceHandle, CFSTR("com.apple.afc"), OutHandle, 0);
     return Result;
 }
예제 #13
0
void handle_device(AMDeviceRef device) {
    if (found_device) return; // handle one device only

    CFStringRef found_device_id = AMDeviceCopyDeviceIdentifier(device);

    if (device_id != NULL) {
        if(strcmp(device_id, CFStringGetCStringPtr(found_device_id, kCFStringEncodingMacRoman)) == 0) {
            found_device = true;
        } else {
            return;
        }
    } else {
        found_device = true;
    }

    CFRetain(device); // don't know if this is necessary?

    printf("[  0%%] Found device (%s), beginning install\n", CFStringGetCStringPtr(found_device_id, kCFStringEncodingMacRoman));

    AMDeviceConnect(device);
    assert(AMDeviceIsPaired(device));
    assert(AMDeviceValidatePairing(device) == 0);
    assert(AMDeviceStartSession(device) == 0);

    CFStringRef path = CFStringCreateWithCString(NULL, app_path, kCFStringEncodingASCII);
    CFURLRef relative_url = CFURLCreateWithFileSystemPath(NULL, path, kCFURLPOSIXPathStyle, false);
    CFURLRef url = CFURLCopyAbsoluteURL(relative_url);

    CFRelease(relative_url);

    int afcFd;
    assert(AMDeviceStartService(device, CFSTR("com.apple.afc"), &afcFd, NULL) == 0);
    assert(AMDeviceStopSession(device) == 0);
    assert(AMDeviceDisconnect(device) == 0);
    assert(AMDeviceTransferApplication(afcFd, path, NULL, transfer_callback, NULL) == 0);

    close(afcFd);

    CFStringRef keys[] = { CFSTR("PackageType") };
    CFStringRef values[] = { CFSTR("Developer") };
    CFDictionaryRef options = CFDictionaryCreate(NULL, (const void **)&keys, (const void **)&values, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);

    AMDeviceConnect(device);
    assert(AMDeviceIsPaired(device));
    assert(AMDeviceValidatePairing(device) == 0);
    assert(AMDeviceStartSession(device) == 0);

    int installFd;
    assert(AMDeviceStartService(device, CFSTR("com.apple.mobile.installation_proxy"), &installFd, NULL) == 0);

    assert(AMDeviceStopSession(device) == 0);
    assert(AMDeviceDisconnect(device) == 0);

    mach_error_t result = AMDeviceInstallApplication(installFd, path, options, install_callback, NULL);
    if (result != 0)
    {
       printf("AMDeviceInstallApplication failed: %d\n", result);
       if (result == -402620388) {
        printf("Please check code signing or something else your app.");
       }
        exit(1);
    }

    close(installFd);

    CFRelease(path);
    CFRelease(options);

    printf("[100%%] Installed package %s\n", app_path);

    if (!debug) exit(0); // no debug phase
    AMDeviceConnect(device);

    assert(AMDeviceIsPaired(device));
    assert(AMDeviceValidatePairing(device) == 0);
    assert(AMDeviceStartSession(device) == 0);

    printf("------ Debug phase ------\n");

    mount_developer_image(device);      // put debugserver on the device
    start_remote_debug_server(device);  // start debugserver
    write_gdb_prep_cmds(device, url);   // dump the necessary gdb commands into a file

    CFRelease(url);

    printf("[100%%] Connecting to remote debug server\n");
    printf("-------------------------\n");

    signal(SIGHUP, gdb_ready_handler);

    pid_t parent = getpid();
    int pid = fork();
    if (pid == 0) {
        system(GDB_SHELL);      // launch gdb
        kill(parent, SIGHUP);  // "No. I am your father."
        _exit(0);
    }
}
예제 #14
0
static void DeviceNotificationCallback(am_device_notification_callback_info *info, void *unknown)
{
    struct am_device *device = info->dev;
    switch (info->msg) {
        case ADNCI_MSG_CONNECTED: {
            if (debug) {
                CFStringRef deviceId = AMDeviceCopyDeviceIdentifier(device);
                CFStringRef str = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("deviceconsole connected: %@"), deviceId);
                CFRelease(deviceId);
                CFShow(str);
                CFRelease(str);
            }
            if (requiredDeviceId) {
                CFStringRef deviceId = AMDeviceCopyDeviceIdentifier(device);
                Boolean isRequiredDevice = CFEqual(deviceId, requiredDeviceId);
                CFRelease(deviceId);
                if (!isRequiredDevice)
                    break;
            }
            if (AMDeviceConnect(device) == MDERR_OK) {
                if (AMDeviceIsPaired(device) && (AMDeviceValidatePairing(device) == MDERR_OK)) {
                    if (AMDeviceStartSession(device) == MDERR_OK) {
                        service_conn_t connection;
                        if (AMDeviceStartService(device, AMSVC_SYSLOG_RELAY, &connection, NULL) == MDERR_OK) {
                            CFSocketRef socket = CFSocketCreateWithNative(kCFAllocatorDefault, connection, kCFSocketDataCallBack, SocketCallback, NULL);
                            if (socket) {
                                CFRunLoopSourceRef source = CFSocketCreateRunLoopSource(kCFAllocatorDefault, socket, 0);
                                if (source) {
                                    CFRunLoopAddSource(CFRunLoopGetMain(), source, kCFRunLoopCommonModes);
                                    AMDeviceRetain(device);
                                    DeviceConsoleConnection *data = malloc(sizeof *data);
                                    data->connection = connection;
                                    data->socket = socket;
                                    data->source = source;
                                    CFDictionarySetValue(liveConnections, device, data);
                                    return;
                                }
                                CFRelease(source);
                            }
                        }
                        AMDeviceStopSession(device);
                    }
                }
            }
            AMDeviceDisconnect(device);
            break;
        }
        case ADNCI_MSG_DISCONNECTED: {
            if (debug) {
                CFStringRef deviceId = AMDeviceCopyDeviceIdentifier(device);
                CFStringRef str = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("deviceconsole disconnected: %@"), deviceId);
                CFRelease(deviceId);
                CFShow(str);
                CFRelease(str);
            }
            DeviceConsoleConnection *data = (DeviceConsoleConnection *)CFDictionaryGetValue(liveConnections, device);
            if (data) {
                CFDictionaryRemoveValue(liveConnections, device);
                AMDeviceRelease(device);
                CFRunLoopRemoveSource(CFRunLoopGetMain(), data->source, kCFRunLoopCommonModes);
                CFRelease(data->source);
                CFRelease(data->socket);
                free(data);
                AMDeviceStopSession(device);
                AMDeviceDisconnect(device);
            }
            break;
        }
        default:
            break;
    }
}
예제 #15
0
void handle_device(AMDeviceRef device) {
    if (found_device) return; // handle one device only

    CFStringRef found_device_id = AMDeviceCopyDeviceIdentifier(device);

    PRINT ("found device id\n");
    if (device_id != NULL) {
        if(strcmp(device_id, CFStringGetCStringPtr(found_device_id, CFStringGetSystemEncoding())) == 0) {
            found_device = true;
        } else {
            return;
        }
    } else {
        if (operation == OP_LIST_DEVICES) {
            printf ("%s\n", CFStringGetCStringPtr(found_device_id, CFStringGetSystemEncoding()));
            CFRetain(device); // don't know if this is necessary?
            return;
        }
        found_device = true;
    }

    CFRetain(device); // don't know if this is necessary?

    PRINT("[  0%%] Found device (%s), beginning install\n", CFStringGetCStringPtr(found_device_id, CFStringGetSystemEncoding()));

    AMDeviceConnect(device);
    assert(AMDeviceIsPaired(device));
    assert(AMDeviceValidatePairing(device) == 0);
    assert(AMDeviceStartSession(device) == 0);

    CFStringRef path = CFStringCreateWithCString(NULL, app_path, kCFStringEncodingASCII);
    CFURLRef relative_url = CFURLCreateWithFileSystemPath(NULL, path, kCFURLPOSIXPathStyle, false);
    CFURLRef url = CFURLCopyAbsoluteURL(relative_url);

    CFRelease(relative_url);

    int afcFd;
	int startServiceAFCRetval = AMDeviceStartService(device, CFSTR("com.apple.afc"), (service_conn_t *) &afcFd, NULL);
	printf("trying to start com.apple.afc : %d\n", startServiceAFCRetval);
	
	if( startServiceAFCRetval )
	{
		sleep(1);
		//printf("trying to start com.apple.afc\n");
		startServiceAFCRetval = AMDeviceStartService(device, CFSTR("com.apple.afc"), (service_conn_t *) &afcFd, NULL);
	}
	printf("trying to start com.apple.afc : %d\n", startServiceAFCRetval);
    assert(startServiceAFCRetval == 0);
    assert(AMDeviceStopSession(device) == 0);
    assert(AMDeviceDisconnect(device) == 0);

    if (operation == OP_INSTALL) {
        assert(AMDeviceTransferApplication(afcFd, path, NULL, transfer_callback, NULL) == 0);
        close(afcFd);
    }

    CFStringRef keys[] = { CFSTR("PackageType") };
    CFStringRef values[] = { CFSTR("Developer") };
    CFDictionaryRef options = CFDictionaryCreate(NULL, (const void **)&keys, (const void **)&values, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);

    AMDeviceConnect(device);
    assert(AMDeviceIsPaired(device));
    assert(AMDeviceValidatePairing(device) == 0);
    assert(AMDeviceStartSession(device) == 0);

    int installFd;
    assert(AMDeviceStartService(device, CFSTR("com.apple.mobile.installation_proxy"), (service_conn_t *) &installFd, NULL) == 0);

    //assert(AMDeviceStopSession(device) == 0);
    //assert(AMDeviceDisconnect(device) == 0);

    if (operation == OP_INSTALL) {
        mach_error_t result = AMDeviceSecureInstallApplication(0, device, url, options, &operation_callback, 0);
        //mach_error_t result = AMDeviceInstallApplication(installFd, path, options, operation_callback, NULL);
        if (result != 0)
        {
			PRINT("AMDeviceInstallApplication failed: %d\n", result);
			exit(EXIT_FAILURE);
        }
    }
	else if (operation == OP_UNINSTALL) {
        mach_error_t result = AMDeviceUninstallApplication (installFd, path, NULL, operation_callback, NULL);
        if (result != 0)
        {
			PRINT("AMDeviceUninstallApplication failed: %d\n", result);
			exit(EXIT_FAILURE);
        }
    }
    
    assert(AMDeviceStopSession(device) == 0);
    assert(AMDeviceDisconnect(device) == 0);


    close(installFd);

    CFRelease(path);
    CFRelease(options);

    if (operation == OP_INSTALL)
        PRINT("[100%%] Installed package %s\n", app_path);
    else if (operation == OP_UNINSTALL)
        PRINT("[100%%] Uninstalled package %s\n", app_path);


    if (!debug) exit(EXIT_SUCCESS); // no debug phase

    AMDeviceConnect(device);
    assert(AMDeviceIsPaired(device));
    assert(AMDeviceValidatePairing(device) == 0);
    assert(AMDeviceStartSession(device) == 0);

    PRINT("------ Debug phase ------\n");

    mount_developer_image(device);      // put debugserver on the device
    start_remote_debug_server(device);  // start debugserver
    write_gdb_prep_cmds(device, url);   // dump the necessary gdb commands into a file

    CFRelease(url);

    PRINT("[100%%] Connecting to remote debug server\n");
    PRINT("-------------------------\n");

    signal(SIGHUP, gdb_ready_handler);

    pid_t parent = getpid();
    int pid = fork();
    if (pid == 0) {
        system(GDB_SHELL);      // launch gdb
        kill(parent, SIGHUP);  // "No. I am your father."
        _exit(EXIT_SUCCESS);
    }
}