diff options
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | include/libirecovery.h | 19 | ||||
-rw-r--r-- | src/irecovery.c | 60 | ||||
-rw-r--r-- | src/libirecovery.c | 34 |
4 files changed, 90 insertions, 27 deletions
@@ -1,4 +1,4 @@ -all: static +all: @echo "Please choose either macosx, linux, or windows" static: @@ -20,7 +20,7 @@ windows: gcc -o irecovery irecovery.c -I. -lirecovery clean: - rm -rf irecovery libirecovery.o libirecovery.so + rm -rf irecovery libirecovery.o libirecovery.so libirecovery.a diff --git a/include/libirecovery.h b/include/libirecovery.h index 342e99b..b489011 100644 --- a/include/libirecovery.h +++ b/include/libirecovery.h @@ -18,14 +18,15 @@ #include <libusb-1.0/libusb.h> -#define kAppleVendorId 0x05AC - -#define IRECV_SUCCESS 0 -#define IRECV_ERROR_NO_DEVICE -1 -#define IRECV_ERROR_OUT_OF_MEMORY -2 -#define IRECV_ERROR_UNABLE_TO_CONNECT -3 +#define IRECV_SUCCESS 0 +#define IRECV_ERROR_NO_DEVICE -1 +#define IRECV_ERROR_OUT_OF_MEMORY -2 +#define IRECV_ERROR_UNABLE_TO_CONNECT -3 +#define IRECV_ERROR_INVALID_INPUT -4 +#define IRECV_ERROR_UNKNOWN -5 enum { + kAppleId = 0x05AC, kKernelMode = 0x1294, kRecoveryMode = 0x1281, kDfuMode = 0x1227 @@ -37,9 +38,11 @@ typedef struct { struct libusb_device_handle* handle; } irecv_device; -int irecv_init(irecv_device** device); +void irecv_set_debug(int level); int irecv_open(irecv_device* device); +int irecv_exit(irecv_device* device); +int irecv_init(irecv_device** device); int irecv_reset(irecv_device* device); int irecv_close(irecv_device* device); -int irecv_exit(irecv_device* device); +int irecv_command(irecv_device* device, const char* command); diff --git a/src/irecovery.c b/src/irecovery.c index 90f975b..51320a5 100644 --- a/src/irecovery.c +++ b/src/irecovery.c @@ -17,9 +17,50 @@ **/ #include <stdio.h> +#include <stdlib.h> +#include <unistd.h> #include <libirecovery.h> +enum { + kResetDevice, kSendCommand +}; + +void print_usage() { + printf("iRecovery - iDevice Recovery Utility\n"); + printf("Usage: ./irecovery [args]\n"); + exit(1); +} + int main(int argc, char** argv) { + int opt = 0; + int action = 0; + char* argument = NULL; + if(argc == 1) print_usage(); + while ((opt = getopt(argc, argv, "dhrc:f:")) > 0) { + switch (opt) { + case 'd': + irecv_set_debug(1); + break; + + case 'h': + print_usage(); + break; + + case 'r': + action = kResetDevice; + break; + + case 'c': + argument = optarg; + action = kSendCommand; + break; + + default: + fprintf(stderr, "Unknown argument\n"); + break; + } + } + irecv_device* device = NULL; if(irecv_init(&device) < 0) { fprintf(stderr, "Unable to initialize libirecovery\n"); @@ -31,27 +72,20 @@ int main(int argc, char** argv) { return -1; } - switch (device->mode) { - case kRecoveryMode: - printf("Found device in recovery mode\n"); + switch(action) { + case kResetDevice: + irecv_reset(device); break; - case kDfuMode: - printf("Found device in DFU mode\n"); - break; - - case kKernelMode: - printf("Found device in kernel mode\n"); + case kSendCommand: + irecv_command(device, argument); break; default: - printf("No device found\n"); + fprintf(stderr, "Unknown action\n"); break; } - printf("Sending USB reset...\n"); - irecv_reset(device); - irecv_exit(device); return 0; } diff --git a/src/libirecovery.c b/src/libirecovery.c index a5b5c84..85967ec 100644 --- a/src/libirecovery.c +++ b/src/libirecovery.c @@ -23,14 +23,13 @@ #include "libirecovery.h" -static unsigned int debug = 1; +static unsigned int irecv_debug = 0; int irecv_init(irecv_device** p_device) { struct libusb_context* usb_context = NULL; libusb_init(&usb_context); - if (debug) - libusb_set_debug(usb_context, 3); + if (irecv_debug) libusb_set_debug(usb_context, 3); irecv_device* device = (irecv_device*) malloc(sizeof(irecv_device)); if (device == NULL) { @@ -60,7 +59,7 @@ int irecv_open(irecv_device* device) { for (i = 0; i < usb_device_count; i++) { usb_device = usb_device_list[i]; libusb_get_device_descriptor(usb_device, &usb_descriptor); - if (usb_descriptor.idVendor == kAppleVendorId) { + if (usb_descriptor.idVendor == kAppleId) { libusb_open(usb_device, &usb_handle); if (usb_handle == NULL) { @@ -115,3 +114,30 @@ int irecv_exit(irecv_device* device) { return IRECV_SUCCESS; } + +void irecv_set_debug(int level) { + printf("Debug has been set to %d\n", level); + irecv_debug = level; +} + +int irecv_command(irecv_device* device, const char* command) { + if(device == NULL || device->handle == NULL) { + return IRECV_ERROR_NO_DEVICE; + } + + ssize_t length = strlen(command); + if(length >= 0x100) { + return IRECV_ERROR_INVALID_INPUT; + } + + int ret = libusb_control_transfer(device->handle, 0x40, 0, 0, 0, (unsigned char*) command, length+1, 100); + if(ret < 0) { + return IRECV_ERROR_UNKNOWN; + } + + return IRECV_SUCCESS; +} + +int irecv_upload(irecv_device* device, const char* filename) { + return IRECV_SUCCESS; +} |