diff options
| author | 2010-06-01 04:34:40 -0400 | |
|---|---|---|
| committer | 2010-06-01 04:34:40 -0400 | |
| commit | 4de6d38c54d9f641006539a06083e423a5d0c9c9 (patch) | |
| tree | 990a89f501eaee4427ea8104a0bcf0dab438b05b /src/idevicerestore.c | |
| parent | 75a3f5f5c6ec5b89659f4e4aacd5d629a3912f22 (diff) | |
| download | idevicerestore-4de6d38c54d9f641006539a06083e423a5d0c9c9.tar.gz idevicerestore-4de6d38c54d9f641006539a06083e423a5d0c9c9.tar.bz2 | |
Began refactoring of code to simplify and seperate device state logic
Diffstat (limited to 'src/idevicerestore.c')
| -rw-r--r-- | src/idevicerestore.c | 623 | 
1 files changed, 9 insertions, 614 deletions
| diff --git a/src/idevicerestore.c b/src/idevicerestore.c index fa685bd..aaff4d6 100644 --- a/src/idevicerestore.c +++ b/src/idevicerestore.c @@ -29,17 +29,20 @@  #include <libimobiledevice/lockdown.h>  #include <libimobiledevice/libimobiledevice.h> +#include "dfu.h"  #include "tss.h"  #include "img3.h"  #include "ipsw.h" +#include "normal.h" +#include "restore.h" +#include "recovery.h"  #include "idevicerestore.h"  #define UNKNOWN_MODE   0 -#define NORMAL_MODE    1 -#define RECOVERY_MODE  2 -#define RESTORE_MODE   3 - -#define ASR_PORT       12345 +#define DFU_MODE       1 +#define NORMAL_MODE    2 +#define RECOVERY_MODE  3 +#define RESTORE_MODE   4  int idevicerestore_debug = 0;  static int idevicerestore_mode = 0; @@ -48,11 +51,6 @@ static int idevicerestore_custom = 0;  void usage(int argc, char* argv[]);  int write_file(const char* filename, char* data, int size); -int recovery_send_ibec(char* ipsw, plist_t tss); -int recovery_send_applelogo(char* ipsw, plist_t tss); -int recovery_send_devicetree(char* ipsw, plist_t tss); -int recovery_send_ramdisk(char* ipsw, plist_t tss); -int recovery_send_kernelcache(char* ipsw, plist_t tss);  int get_tss_data_by_name(plist_t tss, const char* entry, char** path, char** blob);  int get_tss_data_by_path(plist_t tss, const char* path, char** name, char** blob);  void device_callback(const idevice_event_t* event, void *user_data); @@ -379,7 +377,7 @@ int main(int argc, char* argv[]) {  							free(kernelcache_data);  						} else if (!strcmp(datatype, "NORData")) { -							send_nor_data(restore, ipsw, tss_response); +							restore_send_nor_data(restore, ipsw, tss_response);  						} else {  							// Unknown DataType!! @@ -435,375 +433,6 @@ void usage(int argc, char* argv[]) {  	exit(1);  } -int restore_handle_progress_msg(restored_client_t client, plist_t msg) { -	const char operation_name[][35] = { -		"Unknown 1", -		"Unknown 2", -		"Unknown 3", -		"Unknown 4", -		"Unknown 5", -		"Unknown 6", -		"Unknown 7", -		"Unknown 8", -		"Unknown 9", -		"Unknown 10", -		"Unknown 11", -		"Creating partition map", -		"Creating filesystem", -		"Restoring image", -		"Verifying restore", -		"Checking filesystems", -		"Mounting filesystems", -		"Unknown 18", -		"Flashing NOR", -		"Updating baseband", -		"Finalizing NAND epoch update", -		"Unknown 22", -		"Unknown 23", -		"Unknown 24", -		"Unknown 25", -		"Modifying persistent boot-args", -		"Unknown 27", -		"Unknown 28", -		"Waiting for NAND", -		"Unmounting filesystems", -		"Unknown 31", -		"Unknown 32", -		"Waiting for Device...", -		"Unknown 34", -		"Unknown 35", -		"Loading NOR data to flash" -	}; - -	plist_t node = NULL; -	uint64_t operation = 0; -	uint64_t uprogress = 0; -	int progress = 0; - -	node = plist_dict_get_item(msg, "Operation"); -	if (node && PLIST_UINT == plist_get_node_type(node)) { -		plist_get_uint_val(node, &operation); -	} else { -		debug("Failed to parse operation from ProgressMsg plist\n"); -		return 0; -	} - -	node = plist_dict_get_item(msg, "Progress"); -	if (node && PLIST_UINT == plist_get_node_type(node)) { -		plist_get_uint_val(node, &uprogress); -		progress = (int) uprogress; -	} else { -		debug("Failed to parse progress from ProgressMsg plist \n"); -		return 0; -	} - -	if ((progress > 0) && (progress < 100)) -		info("%s - Progress: %llu%\n", operation_name[operation], progress); -	else -		info("%s\n", operation_name[operation]); - -	return 0; -} - -int restore_handle_data_request_msg(idevice_t device, restored_client_t client, plist_t msg, const char *filesystem, const char *kernel) { -	plist_t datatype_node = plist_dict_get_item(msg, "DataType"); -	if (datatype_node && PLIST_STRING == plist_get_node_type(datatype_node)) { -		char *datatype = NULL; -		plist_get_string_val(datatype_node, &datatype); -		if (!strcmp(datatype, "SystemImageData")) { -			asr_send_system_image_data_from_file(device, client, filesystem); -		} else if (!strcmp(datatype, "KernelCache")) { -			restore_send_kernelcache(client, kernel); -		} else if (!strcmp(datatype, "NORData")) { -			send_nor_data(device, client); -		} else { -			// Unknown DataType!! -			error("Unknown DataType\n"); -			return -1; -		} -	} -	return 0; -} - -int restore_handle_status_msg(restored_client_t client, plist_t msg) { -	info("Got status message\n"); -	return 0; -} - -int asr_send_system_image_data_from_file(idevice_t device, restored_client_t client, const char *filesystem) { -	int i = 0; -	char buffer[0x1000]; -	uint32_t recv_bytes = 0; -	memset(buffer, '\0', 0x1000); -	idevice_connection_t connection = NULL; -	idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR; - -	for (i = 0; i < 5; i++) { -		ret = idevice_connect(device, ASR_PORT, &connection); -		if (ret == IDEVICE_E_SUCCESS) -			break; - -		else -			sleep(1); -	} - -	if (ret != IDEVICE_E_SUCCESS) -		return ret; - -	memset(buffer, '\0', 0x1000); -	ret = idevice_connection_receive(connection, buffer, 0x1000, &recv_bytes); -	if (ret != IDEVICE_E_SUCCESS) { -		idevice_disconnect(connection); -		return ret; -	} -	info("Received %d bytes\n", recv_bytes); -	info("%s", buffer); - -	FILE* fd = fopen(filesystem, "rb"); -	if (fd == NULL) { -		idevice_disconnect(connection); -		return ret; -	} - -	fseek(fd, 0, SEEK_END); -	uint64_t len = ftell(fd); -	fseek(fd, 0, SEEK_SET); - -	info("Connected to ASR\n"); -	plist_t dict = plist_new_dict(); -	plist_dict_insert_item(dict, "FEC Slice Stride", plist_new_uint(40)); -	plist_dict_insert_item(dict, "Packet Payload Size", plist_new_uint(1450)); -	plist_dict_insert_item(dict, "Packets Per FEC", plist_new_uint(25)); - -	plist_t payload = plist_new_dict(); -	plist_dict_insert_item(payload, "Port", plist_new_uint(1)); -	plist_dict_insert_item(payload, "Size", plist_new_uint(len)); -	plist_dict_insert_item(dict, "Payload", payload); - -	plist_dict_insert_item(dict, "Stream ID", plist_new_uint(1)); -	plist_dict_insert_item(dict, "Version", plist_new_uint(1)); - -	char* xml = NULL; -	unsigned int dict_size = 0; -	unsigned int sent_bytes = 0; -	plist_to_xml(dict, &xml, &dict_size); - -	ret = idevice_connection_send(connection, xml, dict_size, &sent_bytes); -	if (ret != IDEVICE_E_SUCCESS) { -		idevice_disconnect(connection); -		return ret; -	} - -	info("Sent %d bytes\n", sent_bytes); -	info("%s", xml); -	plist_free(dict); -	free(xml); - -	char* command = NULL; -	do { -		memset(buffer, '\0', 0x1000); -		ret = idevice_connection_receive(connection, buffer, 0x1000, &recv_bytes); -		if (ret != IDEVICE_E_SUCCESS) { -			idevice_disconnect(connection); -			return ret; -		} -		info("Received %d bytes\n", recv_bytes); -		info("%s", buffer); - -		plist_t request = NULL; -		plist_from_xml(buffer, recv_bytes, &request); -		plist_t command_node = plist_dict_get_item(request, "Command"); -		if (command_node && PLIST_STRING == plist_get_node_type(command_node)) { -			plist_get_string_val(command_node, &command); -			if (!strcmp(command, "OOBData")) { -				plist_t oob_length_node = plist_dict_get_item(request, "OOB Length"); -				if (!oob_length_node || PLIST_UINT != plist_get_node_type(oob_length_node)) { -					error("Error fetching OOB Length\n"); -					idevice_disconnect(connection); -					return IDEVICE_E_UNKNOWN_ERROR; -				} -				uint64_t oob_length = 0; -				plist_get_uint_val(oob_length_node, &oob_length); - -				plist_t oob_offset_node = plist_dict_get_item(request, "OOB Offset"); -				if (!oob_offset_node || PLIST_UINT != plist_get_node_type(oob_offset_node)) { -					error("Error fetching OOB Offset\n"); -					idevice_disconnect(connection); -					return IDEVICE_E_UNKNOWN_ERROR; -				} -				uint64_t oob_offset = 0; -				plist_get_uint_val(oob_offset_node, &oob_offset); - -				char* oob_data = (char*) malloc(oob_length); -				if (oob_data == NULL) { -					error("Out of memory\n"); -					idevice_disconnect(connection); -					return IDEVICE_E_UNKNOWN_ERROR; -				} - -				fseek(fd, oob_offset, SEEK_SET); -				if (fread(oob_data, 1, oob_length, fd) != oob_length) { -					error("Unable to read filesystem offset\n"); -					idevice_disconnect(connection); -					free(oob_data); -					return ret; -				} - -				ret = idevice_connection_send(connection, oob_data, oob_length, &sent_bytes); -				if (sent_bytes != oob_length || ret != IDEVICE_E_SUCCESS) { -					error("Unable to send %d bytes to asr\n", sent_bytes); -					idevice_disconnect(connection); -					free(oob_data); -					return ret; -				} -				plist_free(request); -				free(oob_data); -			} -		} - -	} while (strcmp(command, "Payload")); - -	fseek(fd, 0, SEEK_SET); -	char data[1450]; -	for (i = len; i > 0; i -= 1450) { -		int size = 1450; -		if (i < 1450) { -			size = i; -		} - -		if (fread(data, 1, size, fd) != (unsigned int) size) { -			fclose(fd); -			idevice_disconnect(connection); -			error("Error reading filesystem\n"); -			return IDEVICE_E_UNKNOWN_ERROR; -		} - -		ret = idevice_connection_send(connection, data, size, &sent_bytes); -		if (ret != IDEVICE_E_SUCCESS) { -			fclose(fd); -		} - -		if (i % (1450 * 1000) == 0) { -			info("."); -		} -	} - -	info("Done sending filesystem\n"); -	fclose(fd); -	ret = idevice_disconnect(connection); -	return ret; -} - -int restore_send_kernelcache(restored_client_t client, char *kernel_data, int len) { -	info("Sending kernelcache\n"); - -	plist_t kernelcache_node = plist_new_data(kernel_data, len); - -	plist_t dict = plist_new_dict(); -	plist_dict_insert_item(dict, "KernelCacheFile", kernelcache_node); - -	restored_error_t ret = restored_send(client, dict); -	if (ret != RESTORE_E_SUCCESS) { -		error("ERROR: Unable to send kernelcache data\n"); -		plist_free(dict); -		return -1; -	} - -	info("Done sending kernelcache\n"); -	plist_free(dict); -	return 0; -} - -int send_nor_data(restored_client_t client, char* ipsw, plist_t tss) { -	char* llb_path = NULL; -	char* llb_blob = NULL; -	if (get_tss_data_by_name(tss, "LLB", &llb_path, &llb_blob) < 0) { -		error("ERROR: Unable to get LLB info from TSS response\n"); -		return -1; -	} - -	char* llb_filename = strstr(llb_path, "LLB"); -	if (llb_filename == NULL) { -		error("ERROR: Unable to extrac firmware path from LLB filename\n"); -		free(llb_path); -		free(llb_blob); -		return -1; -	} - -	char firmware_path[256]; -	memset(firmware_path, '\0', sizeof(firmware_path)); -	memcpy(firmware_path, llb_path, (llb_filename - 1) - llb_path); -	info("Found firmware path %s\n", firmware_path); - -	char manifest_file[256]; -	memset(manifest_file, '\0', sizeof(manifest_file)); -	snprintf(manifest_file, sizeof(manifest_file), "%s/manifest", firmware_path); -	info("Getting firmware manifest %s\n", manifest_file); - -	int manifest_size = 0; -	char* manifest_data = NULL; -	if (ipsw_extract_to_memory(ipsw, manifest_file, &manifest_data, &manifest_size) < 0) { -		error("ERROR: Unable to extract firmware manifest from ipsw\n"); -		free(llb_path); -		free(llb_blob); -		return -1; -	} - -	char firmware_filename[256]; -	memset(firmware_filename, '\0', sizeof(firmware_filename)); - -	int llb_size = 0; -	char* llb_data = NULL; -	plist_t dict = plist_new_dict(); -	char* filename = strtok(manifest_data, "\n"); -	if (filename != NULL) { -		memset(firmware_filename, '\0', sizeof(firmware_filename)); -		snprintf(firmware_filename, sizeof(firmware_filename), "%s/%s", firmware_path, filename); -		if (get_signed_component_by_path(ipsw, tss, firmware_filename, &llb_data, &llb_size) < 0) { -			error("ERROR: Unable to get signed LLB\n"); -			return -1; -		} - -		plist_dict_insert_item(dict, "LlbImageData", plist_new_data(llb_data, (uint64_t) llb_size)); -	} - -	int nor_size = 0; -	char* nor_data = NULL; -	filename = strtok(NULL, "\n"); -	plist_t norimage_array = plist_new_array(); -	while (filename != NULL) { -		memset(firmware_filename, '\0', sizeof(firmware_filename)); -		snprintf(firmware_filename, sizeof(firmware_filename), "%s/%s", firmware_path, filename); -		if (get_signed_component_by_path(ipsw, tss, firmware_filename, &nor_data, &nor_size) < 0) { -			error("ERROR: Unable to get signed firmware %s\n", firmware_filename); -			break; -		} - -		plist_array_append_item(norimage_array, plist_new_data(nor_data, (uint64_t) nor_size)); -		free(nor_data); -		nor_data = NULL; -		nor_size = 0; -		filename = strtok(NULL, "\n"); -	} -	plist_dict_insert_item(dict, "NorImageData", norimage_array); - -	int sz = 0; -	char* xml = NULL; -	plist_to_xml(dict, &xml, &sz); -	debug("%s", xml); -	free(xml); - -	restored_error_t ret = restored_send(client, dict); -	if (ret != RESTORE_E_SUCCESS) { -		error("ERROR: Unable to send kernelcache data\n"); -		plist_free(dict); -		return -1; -	} - -	plist_free(dict); -	return 0; -} -  int write_file(const char* filename, char* data, int size) {  	debug("Writing data to %s\n", filename);  	FILE* file = fopen(filename, "wb"); @@ -1058,237 +687,3 @@ int get_signed_component_by_path(char* ipsw, plist_t tss, char* path, char** pda  	*psize = size;  	return 0;  } - -static int recovery_send_signed_component(irecv_client_t client, char* ipsw, plist_t tss, char* component) { -	int size = 0; -	char* data = NULL; -	char* path = NULL; -	char* blob = NULL; -	img3_file* img3 = NULL; -	irecv_error_t error = 0; - -	if (get_signed_component_by_name(ipsw, tss, component, &data, &size) < 0) { -		error("ERROR: Unable to get signed component: %s\n", component); -		return -1; -	} - -	info("Sending %s...\n", component); -	error = irecv_send_buffer(client, data, size); -	if (error != IRECV_E_SUCCESS) { -		error("ERROR: Unable to send IMG3: %s\n", path); -		img3_free(img3); -		free(data); -		free(path); -		return -1; -	} - -	if (data) { -		free(data); -		data = NULL; -	} - -	return 0; -} - -static irecv_error_t recovery_open_with_timeout(irecv_client_t* client) { -	int i = 0; -	irecv_error_t error = 0; -	for (i = 10; i > 0; i--) { -		error = irecv_open(client); -		if (error == IRECV_E_SUCCESS) { -			return error; -		} - -		sleep(2); -		info("Retrying connection...\n"); -	} - -	error("ERROR: Unable to connect to recovery device.\n"); -	return error; -} - -int recovery_send_ibec(char* ipsw, plist_t tss) { -	irecv_error_t error = 0; -	irecv_client_t client = NULL; -	char* component = "iBEC"; - -	error = recovery_open_with_timeout(&client); -	if (error != IRECV_E_SUCCESS) { -		return -1; -	} - -	error = irecv_send_command(client, "setenv auto-boot true"); -	if (error != IRECV_E_SUCCESS) { -		error("ERROR: Unable to set auto-boot environmental variable\n"); -		irecv_close(client); -		client = NULL; -		return -1; -	} - -	error = irecv_send_command(client, "saveenv"); -	if (error != IRECV_E_SUCCESS) { -		error("ERROR: Unable to save environmental variable\n"); -		irecv_close(client); -		client = NULL; -		return -1; -	} - -	if (recovery_send_signed_component(client, ipsw, tss, component) < 0) { -		error("ERROR: Unable to send %s to device.\n", component); -		irecv_close(client); -		client = NULL; -		return -1; -	} - -	error = irecv_send_command(client, "go"); -	if (error != IRECV_E_SUCCESS) { -		error("ERROR: Unable to execute %s\n", component); -		irecv_close(client); -		client = NULL; -		return -1; -	} - -	if (client) { -		irecv_close(client); -		client = NULL; -	} -	return 0; -} - -int recovery_send_applelogo(char* ipsw, plist_t tss) { -	irecv_error_t error = 0; -	irecv_client_t client = NULL; -	char* component = "AppleLogo"; - -	info("Sending %s...\n", component); - -	error = recovery_open_with_timeout(&client); -	if (error != IRECV_E_SUCCESS) { -		return -1; -	} - -	if (recovery_send_signed_component(client, ipsw, tss, component) < 0) { -		error("ERROR: Unable to send %s to device.\n", component); -		irecv_close(client); -		client = NULL; -		return -1; -	} - -	error = irecv_send_command(client, "setpicture 1"); -	if (error != IRECV_E_SUCCESS) { -		error("ERROR: Unable to set %s\n", component); -		irecv_close(client); -		client = NULL; -		return -1; -	} - -	error = irecv_send_command(client, "bgcolor 0 0 0"); -	if (error != IRECV_E_SUCCESS) { -		error("ERROR: Unable to display %s\n", component); -		irecv_close(client); -		client = NULL; -		return -1; -	} - -	if (client) { -		irecv_close(client); -		client = NULL; -	} -	return 0; -} - -int recovery_send_devicetree(char* ipsw, plist_t tss) { -	irecv_error_t error = 0; -	irecv_client_t client = NULL; -	char *component = "RestoreDeviceTree"; - -	error = recovery_open_with_timeout(&client); -	if (error != IRECV_E_SUCCESS) { -		return -1; -	} - -	if (recovery_send_signed_component(client, ipsw, tss, component) < 0) { -		error("ERROR: Unable to send %s to device.\n", component); -		irecv_close(client); -		client = NULL; -		return -1; -	} - -	error = irecv_send_command(client, "devicetree"); -	if (error != IRECV_E_SUCCESS) { -		error("ERROR: Unable to execute %s\n", component); -		irecv_close(client); -		client = NULL; -		return -1; -	} - -	if (client) { -		irecv_close(client); -		client = NULL; -	} -	return 0; -} - -int recovery_send_ramdisk(char* ipsw, plist_t tss) { -	irecv_error_t error = 0; -	irecv_client_t client = NULL; -	char *component = "RestoreRamDisk"; - -	error = recovery_open_with_timeout(&client); -	if (error != IRECV_E_SUCCESS) { -		return -1; -	} - -	if (recovery_send_signed_component(client, ipsw, tss, component) < 0) { -		error("ERROR: Unable to send %s to device.\n", component); -		irecv_close(client); -		client = NULL; -		return -1; -	} - -	error = irecv_send_command(client, "ramdisk"); -	if (error != IRECV_E_SUCCESS) { -		error("ERROR: Unable to execute %s\n", component); -		irecv_close(client); -		client = NULL; -		return -1; -	} - -	if (client) { -		irecv_close(client); -		client = NULL; -	} -	return 0; -} - -int recovery_send_kernelcache(char* ipsw, plist_t tss) { -	irecv_error_t error = 0; -	irecv_client_t client = NULL; -	char *component = "RestoreKernelCache"; - -	error = recovery_open_with_timeout(&client); -	if (error != IRECV_E_SUCCESS) { -		return -1; -	} - -	if (recovery_send_signed_component(client, ipsw, tss, component) < 0) { -		error("ERROR: Unable to send %s to device.\n", component); -		irecv_close(client); -		client = NULL; -		return -1; -	} - -	error = irecv_send_command(client, "bootx"); -	if (error != IRECV_E_SUCCESS) { -		error("ERROR: Unable to execute %s\n", component); -		irecv_close(client); -		client = NULL; -		return -1; -	} - -	if (client) { -		irecv_close(client); -		client = NULL; -	} -	return 0; -} | 
