diff options
Diffstat (limited to 'src/dfu.c')
| -rw-r--r-- | src/dfu.c | 128 | 
1 files changed, 63 insertions, 65 deletions
| @@ -36,7 +36,7 @@  static int dfu_progress_callback(irecv_client_t client, const irecv_event_t* event) {  	if (event->type == IRECV_PROGRESS) { -		print_progress_bar(event->progress); +		set_progress('DFUP', (double)event->progress/100.0);  	}  	return 0;  } @@ -49,13 +49,13 @@ int dfu_client_new(struct idevicerestore_client_t* client)  		client->dfu = (struct dfu_client_t*)malloc(sizeof(struct dfu_client_t));  		memset(client->dfu, 0, sizeof(struct dfu_client_t));  		if (client->dfu == NULL) { -			error("ERROR: Out of memory\n"); +			logger(LL_ERROR, "Out of memory\n");  			return -1;  		}  	}  	if (irecv_open_with_ecid_and_attempts(&dfu, client->ecid, 10) != IRECV_E_SUCCESS) { -		error("ERROR: Unable to connect to device in DFU mode\n"); +		logger(LL_ERROR, "Unable to connect to device in DFU mode\n");  		return -1;  	} @@ -67,6 +67,7 @@ int dfu_client_new(struct idevicerestore_client_t* client)  void dfu_client_free(struct idevicerestore_client_t* client)  {  	if(client != NULL) { +		finalize_progress('DFUP');  		if (client->dfu != NULL) {  			if(client->dfu->client != NULL) {  				irecv_close(client->dfu->client); @@ -84,7 +85,6 @@ irecv_device_t dfu_get_irecv_device(struct idevicerestore_client_t* client)  	irecv_error_t dfu_error = IRECV_E_SUCCESS;  	irecv_device_t device = NULL; -	irecv_init();  	if (irecv_open_with_ecid_and_attempts(&dfu, client->ecid, 10) != IRECV_E_SUCCESS) {  		return NULL;  	} @@ -104,22 +104,22 @@ irecv_device_t dfu_get_irecv_device(struct idevicerestore_client_t* client)  	return device;  } -int dfu_send_buffer_with_options(struct idevicerestore_client_t* client, unsigned char* buffer, unsigned int size, unsigned int irecv_options) +int dfu_send_buffer_with_options(struct idevicerestore_client_t* client, const void* buffer, size_t size, unsigned int irecv_options)  {  	irecv_error_t err = 0; -	info("Sending data (%d bytes)...\n", size); +	logger(LL_INFO, "Sending data (%zu bytes)...\n", size); -	err = irecv_send_buffer(client->dfu->client, buffer, size, irecv_options); +	err = irecv_send_buffer(client->dfu->client, (unsigned char*)buffer, size, irecv_options);  	if (err != IRECV_E_SUCCESS) { -		error("ERROR: Unable to send data: %s\n", irecv_strerror(err)); +		logger(LL_ERROR, "Unable to send data: %s\n", irecv_strerror(err));  		return -1;  	}  	return 0;  } -int dfu_send_buffer(struct idevicerestore_client_t* client, unsigned char* buffer, unsigned int size) +int dfu_send_buffer(struct idevicerestore_client_t* client, const void* buffer, size_t size)  {  	return dfu_send_buffer_with_options(client, buffer, size, IRECV_SEND_OPT_DFU_NOTIFY_FINISH);  } @@ -134,8 +134,8 @@ int dfu_send_component(struct idevicerestore_client_t* client, plist_t build_ide  		tss = client->tss_localpolicy;  	} -	unsigned char* component_data = NULL; -	unsigned int component_size = 0; +	void* component_data = NULL; +	size_t component_size = 0;  	if (strcmp(component, "Ap,LocalPolicy") == 0) {  		// If Ap,LocalPolicy => Inject an empty policy @@ -145,19 +145,19 @@ int dfu_send_component(struct idevicerestore_client_t* client, plist_t build_ide  	} else {  		if (tss) {  			if (tss_response_get_path_by_entry(tss, component, &path) < 0) { -				debug("NOTE: No path for component %s in TSS, will fetch from build_identity\n", component); +				logger(LL_DEBUG, "No path for component %s in TSS, will fetch from build_identity\n", component);  			}  		}  		if (!path) {  			if (build_identity_get_component_path(build_identity, component, &path) < 0) { -				error("ERROR: Unable to get path for component '%s'\n", component); +				logger(LL_ERROR, "Unable to get path for component '%s'\n", component);  				free(path);  				return -1;  			}  		}  		if (extract_component(client->ipsw, path, &component_data, &component_size) < 0) { -			error("ERROR: Unable to extract component: %s\n", component); +			logger(LL_ERROR, "Unable to extract component: %s\n", component);  			free(path);  			return -1;  		} @@ -165,11 +165,11 @@ int dfu_send_component(struct idevicerestore_client_t* client, plist_t build_ide  		path = NULL;  	} -	unsigned char* data = NULL; -	uint32_t size = 0; +	void* data = NULL; +	size_t size = 0; -	if (personalize_component(component, component_data, component_size, tss, &data, &size) < 0) { -		error("ERROR: Unable to get personalized component: %s\n", component); +	if (personalize_component(client, component, component_data, component_size, tss, &data, &size) < 0) { +		logger(LL_ERROR, "Unable to get personalized component: %s\n", component);  		free(component_data);  		return -1;  	} @@ -180,14 +180,14 @@ int dfu_send_component(struct idevicerestore_client_t* client, plist_t build_ide  		unsigned char* ticket = NULL;  		unsigned int tsize = 0;  		if (tss_response_get_ap_ticket(client->tss, &ticket, &tsize) < 0) { -			error("ERROR: Unable to get ApTicket from TSS request\n"); +			logger(LL_ERROR, "Unable to get ApTicket from TSS request\n");  			return -1;  		}  		uint32_t fillsize = 0;  		if (tsize % 64 != 0) {  			fillsize = ((tsize / 64) + 1) * 64;  		} -		debug("ticket size = %d\nfillsize = %d\n", tsize, fillsize); +		logger(LL_DEBUG, "ticket size = %d\nfillsize = %d\n", tsize, fillsize);  		unsigned char* newdata = (unsigned char*)malloc(size + fillsize);  		memcpy(newdata, ticket, tsize);  		memset(newdata + tsize, '\xFF', fillsize - tsize); @@ -197,11 +197,13 @@ int dfu_send_component(struct idevicerestore_client_t* client, plist_t build_ide  		size += fillsize;  	} -	info("Sending %s (%d bytes)...\n", component, size); +	logger(LL_INFO, "Sending %s (%zu bytes)...\n", component, size); +	register_progress('DFUP', "Uploading");  	irecv_error_t err = irecv_send_buffer(client->dfu->client, data, size, IRECV_SEND_OPT_DFU_NOTIFY_FINISH); +	finalize_progress('DFUP');  	if (err != IRECV_E_SUCCESS) { -		error("ERROR: Unable to send %s component: %s\n", component, irecv_strerror(err)); +		logger(LL_ERROR, "Unable to send %s component: %s\n", component, irecv_strerror(err));  		free(data);  		return -1;  	} @@ -367,14 +369,14 @@ int dfu_send_component_and_command(struct idevicerestore_client_t* client, plist  	irecv_error_t dfu_error = IRECV_E_SUCCESS;  	if (dfu_send_component(client, build_identity, component) < 0) { -		error("ERROR: Unable to send %s to device.\n", component); +		logger(LL_ERROR, "Unable to send %s to device.\n", component);  		return -1;  	} -	info("INFO: executing command: %s\n", command); +	logger(LL_INFO, "INFO: executing command: %s\n", command);  	dfu_error = irecv_send_command(client->dfu->client, command);  	if (dfu_error != IRECV_E_SUCCESS) { -		error("ERROR: Unable to execute %s\n", command); +		logger(LL_ERROR, "Unable to execute %s\n", command);  		return -1;  	} @@ -385,10 +387,10 @@ int dfu_send_command(struct idevicerestore_client_t* client, const char* command  {  	irecv_error_t dfu_error = IRECV_E_SUCCESS; -	info("INFO: executing command: %s\n", command); +	logger(LL_INFO, "INFO: executing command: %s\n", command);  	dfu_error = irecv_send_command(client->dfu->client, command);  	if (dfu_error != IRECV_E_SUCCESS) { -		error("ERROR: Unable to execute %s\n", command); +		logger(LL_ERROR, "Unable to execute %s\n", command);  		return -1;  	} @@ -399,7 +401,7 @@ int dfu_send_iboot_stage1_components(struct idevicerestore_client_t* client, pli  {  	plist_t manifest_node = plist_dict_get_item(build_identity, "Manifest");  	if (!manifest_node || plist_get_node_type(manifest_node) != PLIST_DICT) { -		error("ERROR: Unable to find manifest node\n"); +		logger(LL_ERROR, "Unable to find manifest node\n");  		return -1;  	} @@ -423,12 +425,12 @@ int dfu_send_iboot_stage1_components(struct idevicerestore_client_t* client, pli  			uint8_t b = 0;  			plist_get_bool_val(iboot_node, &b);  			if (b) { -				debug("DEBUG: %s is loaded by iBoot Stage 1 and iBoot.\n", key); +				logger(LL_DEBUG, "%s is loaded by iBoot Stage 1 and iBoot.\n", key);  			} else { -				debug("DEBUG: %s is loaded by iBoot Stage 1 but not iBoot...\n", key); +				logger(LL_DEBUG, "%s is loaded by iBoot Stage 1 but not iBoot...\n", key);  			}  			if (dfu_send_component_and_command(client, build_identity, key, "firmware") < 0) { -				error("ERROR: Unable to send component '%s' to device.\n", key); +				logger(LL_ERROR, "Unable to send component '%s' to device.\n", key);  				err++;  			}  		} @@ -444,14 +446,14 @@ int dfu_enter_recovery(struct idevicerestore_client_t* client, plist_t build_ide  	int mode = 0;  	if (dfu_client_new(client) < 0) { -		error("ERROR: Unable to connect to DFU device\n"); +		logger(LL_ERROR, "Unable to connect to DFU device\n");  		return -1;  	}  	irecv_get_mode(client->dfu->client, &mode);  	if (mode != IRECV_K_DFU_MODE) { -		info("NOTE: device is not in DFU mode, assuming recovery mode.\n"); +		logger(LL_NOTICE, "device is not in DFU mode, assuming recovery mode.\n");  		client->mode = MODE_RECOVERY;  		return 0;  	} @@ -459,7 +461,7 @@ int dfu_enter_recovery(struct idevicerestore_client_t* client, plist_t build_ide  	mutex_lock(&client->device_event_mutex);  	if (dfu_send_component(client, build_identity, "iBSS") < 0) { -		error("ERROR: Unable to send iBSS to device\n"); +		logger(LL_ERROR, "Unable to send iBSS to device\n");  		irecv_close(client->dfu->client);  		client->dfu->client = NULL;  		return -1; @@ -468,21 +470,21 @@ int dfu_enter_recovery(struct idevicerestore_client_t* client, plist_t build_ide  	if (client->build_major > 8) {  		/* reconnect */ -		debug("Waiting for device to disconnect...\n"); +		logger(LL_DEBUG, "Waiting for device to disconnect...\n");  		cond_wait_timeout(&client->device_event_cond, &client->device_event_mutex, 10000);  		if (client->mode != MODE_UNKNOWN || (client->flags & FLAG_QUIT)) {  			mutex_unlock(&client->device_event_mutex);  			if (!(client->flags & FLAG_QUIT)) { -				error("ERROR: Device did not disconnect. Possibly invalid iBSS. Reset device and try again.\n"); +				logger(LL_ERROR, "Device did not disconnect. Possibly invalid iBSS. Reset device and try again.\n");  			}  			return -1;  		} -		debug("Waiting for device to reconnect...\n"); +		logger(LL_DEBUG, "Waiting for device to reconnect...\n");  		cond_wait_timeout(&client->device_event_cond, &client->device_event_mutex, 10000);  		if ((client->mode != MODE_DFU && client->mode != MODE_RECOVERY) || (client->flags & FLAG_QUIT)) {  			mutex_unlock(&client->device_event_mutex);  			if (!(client->flags & FLAG_QUIT)) { -				error("ERROR: Device did not reconnect in DFU or recovery mode. Possibly invalid iBSS. Reset device and try again.\n"); +				logger(LL_ERROR, "Device did not reconnect in DFU or recovery mode. Possibly invalid iBSS. Reset device and try again.\n");  			}  			return -1;  		} @@ -494,7 +496,7 @@ int dfu_enter_recovery(struct idevicerestore_client_t* client, plist_t build_ide  		unsigned int nonce_size = 0;  		int nonce_changed = 0;  		if (dfu_get_ap_nonce(client, &nonce, &nonce_size) < 0) { -			error("ERROR: Unable to get ApNonce from device!\n"); +			logger(LL_ERROR, "Unable to get ApNonce from device!\n");  			return -1;  		} @@ -509,29 +511,25 @@ int dfu_enter_recovery(struct idevicerestore_client_t* client, plist_t build_ide  			free(nonce);  		} -		info("Nonce: "); -		int i; -		for (i = 0; i < client->nonce_size; i++) { -			info("%02x ", client->nonce[i]); -		} -		info("\n"); +		logger(LL_INFO, "Nonce: "); +		logger_dump_hex(LL_INFO, client->nonce, client->nonce_size);  		if (nonce_changed && !(client->flags & FLAG_CUSTOM)) {  			// Welcome iOS5. We have to re-request the TSS with our nonce.  			plist_free(client->tss);  			if (get_tss_response(client, build_identity, &client->tss) < 0) { -				error("ERROR: Unable to get SHSH blobs for this device\n"); +				logger(LL_ERROR, "Unable to get SHSH blobs for this device\n");  				return -1;  			}  			if (!client->tss) { -				error("ERROR: can't continue without TSS\n"); +				logger(LL_ERROR, "can't continue without TSS\n");  				return -1;  			}  			fixup_tss(client->tss);  		}  		if (irecv_usb_set_configuration(client->dfu->client, 1) < 0) { -			error("ERROR: set configuration failed\n"); +			logger(LL_ERROR, "set configuration failed\n");  		}  		mutex_lock(&client->device_event_mutex); @@ -541,7 +539,7 @@ int dfu_enter_recovery(struct idevicerestore_client_t* client, plist_t build_ide  			// Without this empty policy file & its special signature, iBEC won't start.  			if (dfu_send_component_and_command(client, build_identity, "Ap,LocalPolicy", "lpolrestore") < 0) {  				mutex_unlock(&client->device_event_mutex); -				error("ERROR: Unable to send Ap,LocalPolicy to device\n"); +				logger(LL_ERROR, "Unable to send Ap,LocalPolicy to device\n");  				irecv_close(client->dfu->client);  				client->dfu->client = NULL;  				return -1; @@ -554,17 +552,17 @@ int dfu_enter_recovery(struct idevicerestore_client_t* client, plist_t build_ide  				boot_stage = strtoul(value, NULL, 0);  			}  			if (boot_stage > 0) { -				info("iBoot boot-stage=%s\n", value); +				logger(LL_INFO, "iBoot boot-stage=%s\n", value);  				free(value);  				value = NULL;  				if (boot_stage != 1) { -					error("ERROR: iBoot should be at boot stage 1, continuing anyway...\n"); +					logger(LL_ERROR, "iBoot should be at boot stage 1, continuing anyway...\n");  				}  			}  			if (dfu_send_iboot_stage1_components(client, build_identity) < 0) {  				mutex_unlock(&client->device_event_mutex); -				error("ERROR: Unable to send iBoot stage 1 components to device\n"); +				logger(LL_ERROR, "Unable to send iBoot stage 1 components to device\n");  				irecv_close(client->dfu->client);  				client->dfu->client = NULL;  				return -1; @@ -572,7 +570,7 @@ int dfu_enter_recovery(struct idevicerestore_client_t* client, plist_t build_ide  			if (dfu_send_command(client, "setenv auto-boot false") < 0) {  				mutex_unlock(&client->device_event_mutex); -				error("ERROR: Unable to send command to device\n"); +				logger(LL_ERROR, "Unable to send command to device\n");  				irecv_close(client->dfu->client);  				client->dfu->client = NULL;  				return -1; @@ -580,7 +578,7 @@ int dfu_enter_recovery(struct idevicerestore_client_t* client, plist_t build_ide  			if (dfu_send_command(client, "saveenv") < 0) {  				mutex_unlock(&client->device_event_mutex); -				error("ERROR: Unable to send command to device\n"); +				logger(LL_ERROR, "Unable to send command to device\n");  				irecv_close(client->dfu->client);  				client->dfu->client = NULL;  				return -1; @@ -588,7 +586,7 @@ int dfu_enter_recovery(struct idevicerestore_client_t* client, plist_t build_ide  			if (dfu_send_command(client, "setenvnp boot-args rd=md0 nand-enable-reformat=1 -progress -restore") < 0) {  				mutex_unlock(&client->device_event_mutex); -				error("ERROR: Unable to send command to device\n"); +				logger(LL_ERROR, "Unable to send command to device\n");  				irecv_close(client->dfu->client);  				client->dfu->client = NULL;  				return -1; @@ -596,7 +594,7 @@ int dfu_enter_recovery(struct idevicerestore_client_t* client, plist_t build_ide  			if (dfu_send_component(client, build_identity, "RestoreLogo") < 0) {  				mutex_unlock(&client->device_event_mutex); -				error("ERROR: Unable to send RestoreDCP to device\n"); +				logger(LL_ERROR, "Unable to send RestoreDCP to device\n");  				irecv_close(client->dfu->client);  				client->dfu->client = NULL;  				return -1; @@ -604,7 +602,7 @@ int dfu_enter_recovery(struct idevicerestore_client_t* client, plist_t build_ide  			if (dfu_send_command(client, "setpicture 4") < 0) {  				mutex_unlock(&client->device_event_mutex); -				error("ERROR: Unable to send command to device\n"); +				logger(LL_ERROR, "Unable to send command to device\n");  				irecv_close(client->dfu->client);  				client->dfu->client = NULL;  				return -1; @@ -612,7 +610,7 @@ int dfu_enter_recovery(struct idevicerestore_client_t* client, plist_t build_ide  			if (dfu_send_command(client, "bgcolor 0 0 0") < 0) {  				mutex_unlock(&client->device_event_mutex); -				error("ERROR: Unable to send command to device\n"); +				logger(LL_ERROR, "Unable to send command to device\n");  				irecv_close(client->dfu->client);  				client->dfu->client = NULL;  				return -1; @@ -622,7 +620,7 @@ int dfu_enter_recovery(struct idevicerestore_client_t* client, plist_t build_ide  		/* send iBEC */  		if (dfu_send_component(client, build_identity, "iBEC") < 0) {  			mutex_unlock(&client->device_event_mutex); -			error("ERROR: Unable to send iBEC to device\n"); +			logger(LL_ERROR, "Unable to send iBEC to device\n");  			irecv_close(client->dfu->client);  			client->dfu->client = NULL;  			return -1; @@ -632,7 +630,7 @@ int dfu_enter_recovery(struct idevicerestore_client_t* client, plist_t build_ide  			sleep(1);  			if (irecv_send_command_breq(client->dfu->client, "go", 1) != IRECV_E_SUCCESS) {  				mutex_unlock(&client->device_event_mutex); -				error("ERROR: Unable to execute iBEC\n"); +				logger(LL_ERROR, "Unable to execute iBEC\n");  				return -1;  			} @@ -643,28 +641,28 @@ int dfu_enter_recovery(struct idevicerestore_client_t* client, plist_t build_ide  		dfu_client_free(client);  	} -	debug("Waiting for device to disconnect...\n"); +	logger(LL_DEBUG, "Waiting for device to disconnect...\n");  	cond_wait_timeout(&client->device_event_cond, &client->device_event_mutex, 10000);  	if (client->mode != MODE_UNKNOWN || (client->flags & FLAG_QUIT)) {  		mutex_unlock(&client->device_event_mutex);  		if (!(client->flags & FLAG_QUIT)) { -			error("ERROR: Device did not disconnect. Possibly invalid %s. Reset device and try again.\n", (client->build_major > 8) ? "iBEC" : "iBSS"); +			logger(LL_ERROR, "Device did not disconnect. Possibly invalid %s. Reset device and try again.\n", (client->build_major > 8) ? "iBEC" : "iBSS");  		}  		return -1;  	} -	debug("Waiting for device to reconnect in recovery mode...\n"); +	logger(LL_DEBUG, "Waiting for device to reconnect in recovery mode...\n");  	cond_wait_timeout(&client->device_event_cond, &client->device_event_mutex, 10000);  	if (client->mode != MODE_RECOVERY || (client->flags & FLAG_QUIT)) {  		mutex_unlock(&client->device_event_mutex);  		if (!(client->flags & FLAG_QUIT)) { -			error("ERROR: Device did not reconnect in recovery mode. Possibly invalid %s. Reset device and try again.\n", (client->build_major > 8) ? "iBEC" : "iBSS"); +			logger(LL_ERROR, "Device did not reconnect in recovery mode. Possibly invalid %s. Reset device and try again.\n", (client->build_major > 8) ? "iBEC" : "iBSS");  		}  		return -1;  	}  	mutex_unlock(&client->device_event_mutex);  	if (recovery_client_new(client) < 0) { -		error("ERROR: Unable to connect to recovery device\n"); +		logger(LL_ERROR, "Unable to connect to recovery device\n");  		if (client->recovery->client) {  			irecv_close(client->recovery->client);  			client->recovery->client = NULL; | 
