summaryrefslogtreecommitdiffstats
path: root/heimdall/source
diff options
context:
space:
mode:
Diffstat (limited to 'heimdall/source')
-rw-r--r--heimdall/source/BridgeManager.cpp307
-rw-r--r--heimdall/source/BridgeManager.h7
-rw-r--r--heimdall/source/Interface.cpp409
-rw-r--r--heimdall/source/Interface.h255
-rw-r--r--heimdall/source/InterfaceManager.cpp325
-rw-r--r--heimdall/source/InterfaceManager.h123
-rw-r--r--heimdall/source/OutboundPacket.h2
-rwxr-xr-xheimdall/source/PitData.cpp284
-rwxr-xr-xheimdall/source/PitData.h345
-rw-r--r--heimdall/source/main.cpp342
10 files changed, 1021 insertions, 1378 deletions
diff --git a/heimdall/source/BridgeManager.cpp b/heimdall/source/BridgeManager.cpp
index caa3978..204d87f 100644
--- a/heimdall/source/BridgeManager.cpp
+++ b/heimdall/source/BridgeManager.cpp
@@ -27,6 +27,8 @@
// Heimdall
#include "BeginDumpPacket.h"
#include "BridgeManager.h"
+#include "DeviceInfoPacket.h"
+#include "DeviceInfoResponse.h"
#include "DumpPartFileTransferPacket.h"
#include "DumpPartPitFilePacket.h"
#include "DumpResponse.h"
@@ -37,7 +39,7 @@
#include "FlashPartFileTransferPacket.h"
#include "FlashPartPitFilePacket.h"
#include "InboundPacket.h"
-#include "InterfaceManager.h"
+#include "Interface.h"
#include "OutboundPacket.h"
#include "PitFilePacket.h"
#include "PitFileResponse.h"
@@ -92,7 +94,7 @@ BridgeManager::~BridgeManager()
if (detachedDriver)
{
- InterfaceManager::Print("Re-attaching kernel driver...\n");
+ Interface::Print("Re-attaching kernel driver...\n");
libusb_attach_kernel_driver(deviceHandle, interfaceIndex);
}
@@ -108,13 +110,50 @@ BridgeManager::~BridgeManager()
libusb_exit(libusbContext);
}
+bool BridgeManager::DetectDevice(void)
+{
+ // Initialise libusb-1.0
+ int result = libusb_init(&libusbContext);
+ if (result != LIBUSB_SUCCESS)
+ {
+ Interface::PrintError("Failed to initialise libusb. Error: %i\n", result);
+ return (false);
+ }
+
+ // Get handle to Galaxy S device
+ struct libusb_device **devices;
+ int deviceCount = libusb_get_device_list(libusbContext, &devices);
+
+ for (int deviceIndex = 0; deviceIndex < deviceCount; deviceIndex++)
+ {
+ libusb_device_descriptor descriptor;
+ libusb_get_device_descriptor(devices[deviceIndex], &descriptor);
+
+ for (int i = 0; i < BridgeManager::kSupportedDeviceCount; i++)
+ {
+ if (descriptor.idVendor == supportedDevices[i].vendorId && descriptor.idProduct == supportedDevices[i].productId)
+ {
+ libusb_free_device_list(devices, deviceCount);
+
+ Interface::Print("Device detected");
+ return (true);
+ }
+ }
+ }
+
+ libusb_free_device_list(devices, deviceCount);
+
+ Interface::Print("Failed to detect compatible device\n");
+ return (false);
+}
+
bool BridgeManager::Initialise(void)
{
// Initialise libusb-1.0
int result = libusb_init(&libusbContext);
if (result != LIBUSB_SUCCESS)
{
- InterfaceManager::PrintError("Failed to initialise libusb. Error: %i\n", result);
+ Interface::PrintError("Failed to initialise libusb. Error: %i\n", result);
return (false);
}
@@ -145,14 +184,14 @@ bool BridgeManager::Initialise(void)
if (!heimdallDevice)
{
- InterfaceManager::PrintError("Failed to detect compatible device\n");
+ Interface::PrintError("Failed to detect compatible device\n");
return (false);
}
result = libusb_open(heimdallDevice, &deviceHandle);
if (result != LIBUSB_SUCCESS)
{
- InterfaceManager::PrintError("Failed to access device. Error: %i\n", result);
+ Interface::PrintError("Failed to access device. Error: %i\n", result);
return (false);
}
@@ -160,7 +199,7 @@ bool BridgeManager::Initialise(void)
result = libusb_get_device_descriptor(heimdallDevice, &deviceDescriptor);
if (result != LIBUSB_SUCCESS)
{
- InterfaceManager::PrintError("Failed to retrieve device description\n");
+ Interface::PrintError("Failed to retrieve device description\n");
return (false);
}
@@ -170,36 +209,36 @@ bool BridgeManager::Initialise(void)
if (libusb_get_string_descriptor_ascii(deviceHandle, deviceDescriptor.iManufacturer,
stringBuffer, 128) >= 0)
{
- InterfaceManager::Print(" Manufacturer: \"%s\"\n", stringBuffer);
+ Interface::Print(" Manufacturer: \"%s\"\n", stringBuffer);
}
if (libusb_get_string_descriptor_ascii(deviceHandle, deviceDescriptor.iProduct,
stringBuffer, 128) >= 0)
{
- InterfaceManager::Print(" Product: \"%s\"\n", stringBuffer);
+ Interface::Print(" Product: \"%s\"\n", stringBuffer);
}
if (libusb_get_string_descriptor_ascii(deviceHandle, deviceDescriptor.iSerialNumber,
stringBuffer, 128) >= 0)
{
- InterfaceManager::Print(" Serial No: \"%s\"\n", stringBuffer);
+ Interface::Print(" Serial No: \"%s\"\n", stringBuffer);
}
- InterfaceManager::Print("\n length: %d\n", deviceDescriptor.bLength);
- InterfaceManager::Print(" device class: %d\n", deviceDescriptor.bDeviceClass);
- InterfaceManager::Print(" S/N: %d\n", deviceDescriptor.iSerialNumber);
- InterfaceManager::Print(" VID:PID: %04X:%04X\n", deviceDescriptor.idVendor, deviceDescriptor.idProduct);
- InterfaceManager::Print(" bcdDevice: %04X\n", deviceDescriptor.bcdDevice);
- InterfaceManager::Print(" iMan:iProd:iSer: %d:%d:%d\n", deviceDescriptor.iManufacturer, deviceDescriptor.iProduct,
+ Interface::Print("\n length: %d\n", deviceDescriptor.bLength);
+ Interface::Print(" device class: %d\n", deviceDescriptor.bDeviceClass);
+ Interface::Print(" S/N: %d\n", deviceDescriptor.iSerialNumber);
+ Interface::Print(" VID:PID: %04X:%04X\n", deviceDescriptor.idVendor, deviceDescriptor.idProduct);
+ Interface::Print(" bcdDevice: %04X\n", deviceDescriptor.bcdDevice);
+ Interface::Print(" iMan:iProd:iSer: %d:%d:%d\n", deviceDescriptor.iManufacturer, deviceDescriptor.iProduct,
deviceDescriptor.iSerialNumber);
- InterfaceManager::Print(" nb confs: %d\n", deviceDescriptor.bNumConfigurations);
+ Interface::Print(" nb confs: %d\n", deviceDescriptor.bNumConfigurations);
}
libusb_config_descriptor *configDescriptor;
result = libusb_get_config_descriptor(heimdallDevice, 0, &configDescriptor);
if (result != LIBUSB_SUCCESS || !configDescriptor)
{
- InterfaceManager::PrintError("Failed to retrieve config descriptor\n");
+ Interface::PrintError("Failed to retrieve config descriptor\n");
return (false);
}
@@ -212,9 +251,9 @@ bool BridgeManager::Initialise(void)
{
if (verbose)
{
- InterfaceManager::Print("\ninterface[%d].altsetting[%d]: num endpoints = %d\n",
+ Interface::Print("\ninterface[%d].altsetting[%d]: num endpoints = %d\n",
i, j, configDescriptor->usb_interface[i].altsetting[j].bNumEndpoints);
- InterfaceManager::Print(" Class.SubClass.Protocol: %02X.%02X.%02X\n",
+ Interface::Print(" Class.SubClass.Protocol: %02X.%02X.%02X\n",
configDescriptor->usb_interface[i].altsetting[j].bInterfaceClass,
configDescriptor->usb_interface[i].altsetting[j].bInterfaceSubClass,
configDescriptor->usb_interface[i].altsetting[j].bInterfaceProtocol);
@@ -230,9 +269,9 @@ bool BridgeManager::Initialise(void)
if (verbose)
{
- InterfaceManager::Print(" endpoint[%d].address: %02X\n", k, endpoint->bEndpointAddress);
- InterfaceManager::Print(" max packet size: %04X\n", endpoint->wMaxPacketSize);
- InterfaceManager::Print(" polling interval: %02X\n", endpoint->bInterval);
+ Interface::Print(" endpoint[%d].address: %02X\n", k, endpoint->bEndpointAddress);
+ Interface::Print(" max packet size: %04X\n", endpoint->wMaxPacketSize);
+ Interface::Print(" polling interval: %02X\n", endpoint->bInterval);
}
if (endpoint->bEndpointAddress & LIBUSB_ENDPOINT_IN)
@@ -258,11 +297,11 @@ bool BridgeManager::Initialise(void)
if (result != LIBUSB_SUCCESS)
{
- InterfaceManager::PrintError("Failed to find correct interface configuration\n");
+ Interface::PrintError("Failed to find correct interface configuration\n");
return (false);
}
- InterfaceManager::Print("\nClaiming interface...");
+ Interface::Print("\nClaiming interface...");
result = libusb_claim_interface(deviceHandle, interfaceIndex);
#ifdef OS_LINUX
@@ -270,9 +309,9 @@ bool BridgeManager::Initialise(void)
if (result != LIBUSB_SUCCESS)
{
detachedDriver = true;
- InterfaceManager::Print(" Failed. Attempting to detach driver...\n");
+ Interface::Print(" Failed. Attempting to detach driver...\n");
libusb_detach_kernel_driver(deviceHandle, interfaceIndex);
- InterfaceManager::Print("Claiming interface again...");
+ Interface::Print("Claiming interface again...");
result = libusb_claim_interface(deviceHandle, interfaceIndex);
}
@@ -280,28 +319,28 @@ bool BridgeManager::Initialise(void)
if (result != LIBUSB_SUCCESS)
{
- InterfaceManager::PrintError(" Failed!\n");
+ Interface::PrintError(" Failed!\n");
return (false);
}
- InterfaceManager::Print(" Success\n");
+ Interface::Print(" Success\n");
- InterfaceManager::Print("Setting up interface...");
+ Interface::Print("Setting up interface...");
result = libusb_set_interface_alt_setting(deviceHandle, interfaceIndex, altSettingIndex);
if (result != LIBUSB_SUCCESS)
{
- InterfaceManager::PrintError(" Failed!\n");
+ Interface::PrintError(" Failed!\n");
return (false);
}
- InterfaceManager::Print(" Success\n");
+ Interface::Print(" Success\n");
return (true);
}
bool BridgeManager::BeginSession(void) const
{
- InterfaceManager::Print("Beginning session...\n");
+ Interface::Print("Beginning session...\n");
unsigned char *dataBuffer = new unsigned char[7];
@@ -309,7 +348,7 @@ bool BridgeManager::BeginSession(void) const
if (result < 0)
{
- InterfaceManager::PrintError("Failed to initialise usb communication!\n");
+ Interface::PrintError("Failed to initialise usb communication!\n");
delete [] dataBuffer;
return (false);
}
@@ -322,7 +361,7 @@ bool BridgeManager::BeginSession(void) const
result = libusb_control_transfer(deviceHandle, LIBUSB_REQUEST_TYPE_CLASS, 0x20, 0x0, 0, dataBuffer, 7, 1000);
if (result < 0)
{
- InterfaceManager::PrintError("Failed to initialise usb communication!\n");
+ Interface::PrintError("Failed to initialise usb communication!\n");
delete [] dataBuffer;
return (false);
}
@@ -330,7 +369,7 @@ bool BridgeManager::BeginSession(void) const
result = libusb_control_transfer(deviceHandle, LIBUSB_REQUEST_TYPE_CLASS, 0x22, 0x3, 0, nullptr, 0, 1000);
if (result < 0)
{
- InterfaceManager::PrintError("Failed to initialise usb communication!\n");
+ Interface::PrintError("Failed to initialise usb communication!\n");
delete [] dataBuffer;
return (false);
}
@@ -338,7 +377,7 @@ bool BridgeManager::BeginSession(void) const
result = libusb_control_transfer(deviceHandle, LIBUSB_REQUEST_TYPE_CLASS, 0x22, 0x2, 0, nullptr, 0, 1000);
if (result < 0)
{
- InterfaceManager::PrintError("Failed to initialise usb communication!\n");
+ Interface::PrintError("Failed to initialise usb communication!\n");
delete [] dataBuffer;
return (false);
}
@@ -351,7 +390,7 @@ bool BridgeManager::BeginSession(void) const
result = libusb_control_transfer(deviceHandle, LIBUSB_REQUEST_TYPE_CLASS, 0x20, 0x0, 0, dataBuffer, 7, 1000);
if (result < 0)
{
- InterfaceManager::PrintError("Failed to initialise usb communication!\n");
+ Interface::PrintError("Failed to initialise usb communication!\n");
delete [] dataBuffer;
return (false);
}
@@ -359,12 +398,12 @@ bool BridgeManager::BeginSession(void) const
result = libusb_control_transfer(deviceHandle, LIBUSB_REQUEST_TYPE_CLASS, 0x22, 0x2, 0, nullptr, 0, 1000);
if (result < 0)
{
- InterfaceManager::PrintError("Failed to initialise usb communication!\n");
+ Interface::PrintError("Failed to initialise usb communication!\n");
delete [] dataBuffer;
return (false);
}
- InterfaceManager::Print("Handshaking with Loke...");
+ Interface::Print("Handshaking with Loke...");
int dataTransferred;
@@ -374,10 +413,10 @@ bool BridgeManager::BeginSession(void) const
result = libusb_bulk_transfer(deviceHandle, outEndpoint, dataBuffer, 4, &dataTransferred, 1000);
if (result < 0)
{
- InterfaceManager::PrintError(" Failed!\n");
+ Interface::PrintError(" Failed!\n");
if (verbose)
- InterfaceManager::PrintError("ERROR: Failed to send data: \"%s\"\n", dataBuffer);
+ Interface::PrintError("ERROR: Failed to send data: \"%s\"\n", dataBuffer);
delete [] dataBuffer;
return (false);
@@ -385,10 +424,10 @@ bool BridgeManager::BeginSession(void) const
if (dataTransferred != 4)
{
- InterfaceManager::PrintError(" Failed!\n");
+ Interface::PrintError(" Failed!\n");
if (verbose)
- InterfaceManager::PrintError("ERROR: Failed to complete sending data: \"%s\"\n", dataBuffer);
+ Interface::PrintError("ERROR: Failed to complete sending data: \"%s\"\n", dataBuffer);
delete [] dataBuffer;
return (false);
@@ -400,32 +439,32 @@ bool BridgeManager::BeginSession(void) const
result = libusb_bulk_transfer(deviceHandle, inEndpoint, dataBuffer, 7, &dataTransferred, 1000);
if (result < 0)
{
- InterfaceManager::PrintError(" Failed!\n");
+ Interface::PrintError(" Failed!\n");
if (verbose)
- InterfaceManager::PrintError("ERROR: Failed to receive response\n");
+ Interface::PrintError("ERROR: Failed to receive response\n");
delete [] dataBuffer;
return (false);;
}
if (dataTransferred != 4 || memcmp(dataBuffer, "LOKE", 4) != 0)
{
- InterfaceManager::PrintError(" Failed!\n");
+ Interface::PrintError(" Failed!\n");
if (verbose)
- InterfaceManager::PrintError("ERROR: Unexpected communication.\nExpected: \"%s\"\nReceived: \"%s\"\n", "LOKE", dataBuffer);
+ Interface::PrintError("ERROR: Unexpected communication.\nExpected: \"%s\"\nReceived: \"%s\"\n", "LOKE", dataBuffer);
delete [] dataBuffer;
return (false);
}
- InterfaceManager::Print(" Success\n\n");
+ Interface::Print(" Success\n\n");
return (true);
}
-bool BridgeManager::EndSession(void) const
+bool BridgeManager::EndSession(bool reboot) const
{
- InterfaceManager::Print("Ending session...\n");
+ Interface::Print("Ending session...\n");
EndSessionPacket *endSessionPacket = new EndSessionPacket(EndSessionPacket::kRequestEndSession);
bool success = SendPacket(endSessionPacket);
@@ -433,7 +472,7 @@ bool BridgeManager::EndSession(void) const
if (!success)
{
- InterfaceManager::PrintError("Failed to send end session packet!\n");
+ Interface::PrintError("Failed to send end session packet!\n");
return (false);
}
@@ -443,10 +482,35 @@ bool BridgeManager::EndSession(void) const
if (!success)
{
- InterfaceManager::PrintError("Failed to receive session end confirmation!\n");
+ Interface::PrintError("Failed to receive session end confirmation!\n");
return (false);
}
+ if (reboot)
+ {
+ Interface::Print("Rebooting device...\n");
+
+ EndSessionPacket *rebootDevicePacket = new EndSessionPacket(EndSessionPacket::kRequestRebootDevice);
+ bool success = SendPacket(rebootDevicePacket);
+ delete rebootDevicePacket;
+
+ if (!success)
+ {
+ Interface::PrintError("Failed to send reboot device packet!\n");
+ return (false);
+ }
+
+ ResponsePacket *rebootDeviceResponse = new ResponsePacket(ResponsePacket::kResponseTypeEndSession);
+ success = ReceivePacket(rebootDeviceResponse);
+ delete rebootDeviceResponse;
+
+ if (!success)
+ {
+ Interface::PrintError("Failed to receive reboot confirmation!\n");
+ return (false);
+ }
+ }
+
return (true);
}
@@ -464,13 +528,13 @@ bool BridgeManager::SendPacket(OutboundPacket *packet, int timeout) const
int retryDelay = (communicationDelay > 250) ? communicationDelay : 250;
if (verbose)
- InterfaceManager::PrintError("Error %i whilst sending packet. ", result);
+ Interface::PrintError("Error %i whilst sending packet. ", result);
// Retry
for (int i = 0; i < 5; i++)
{
if (verbose)
- InterfaceManager::PrintError(" Retrying...\n");
+ Interface::PrintError(" Retrying...\n");
// Wait longer each retry
Sleep(retryDelay * (i + 1));
@@ -482,11 +546,11 @@ bool BridgeManager::SendPacket(OutboundPacket *packet, int timeout) const
break;
if (verbose)
- InterfaceManager::PrintError("Error %i whilst sending packet. ", result);
+ Interface::PrintError("Error %i whilst sending packet. ", result);
}
if (verbose)
- InterfaceManager::PrintError("\n");
+ Interface::PrintError("\n");
}
if (communicationDelay != 0)
@@ -510,13 +574,13 @@ bool BridgeManager::ReceivePacket(InboundPacket *packet, int timeout) const
int retryDelay = (communicationDelay > 250) ? communicationDelay : 250;
if (verbose)
- InterfaceManager::PrintError("Error %i whilst receiving packet. ", result);
+ Interface::PrintError("Error %i whilst receiving packet. ", result);
// Retry
for (int i = 0; i < 5; i++)
{
if (verbose)
- InterfaceManager::PrintError(" Retrying\n");
+ Interface::PrintError(" Retrying\n");
// Wait longer each retry
Sleep(retryDelay * (i + 1));
@@ -528,7 +592,7 @@ bool BridgeManager::ReceivePacket(InboundPacket *packet, int timeout) const
break;
if (verbose)
- InterfaceManager::PrintError("Error %i whilst receiving packet. ", result);
+ Interface::PrintError("Error %i whilst receiving packet. ", result);
if (i >= 3)
{
@@ -538,7 +602,7 @@ bool BridgeManager::ReceivePacket(InboundPacket *packet, int timeout) const
}
if (verbose)
- InterfaceManager::PrintError("\n");
+ Interface::PrintError("\n");
}
if (communicationDelay != 0)
@@ -552,6 +616,24 @@ bool BridgeManager::ReceivePacket(InboundPacket *packet, int timeout) const
return (packet->Unpack());
}
+bool BridgeManager::RequestDeviceInfo(unsigned int request, int *result) const
+{
+ DeviceInfoPacket deviceInfoPacket(request);
+ bool success = SendPacket(&deviceInfoPacket);
+
+ if (!success)
+ {
+ Interface::PrintError("Failed to request device info packet!\nFailed Request: %d\n");
+ return (false);
+ }
+
+ DeviceInfoResponse deviceInfoResponse;
+ success = ReceivePacket(&deviceInfoResponse);
+ *result = deviceInfoResponse.GetUnknown();
+
+ return (true);
+}
+
bool BridgeManager::SendPitFile(FILE *file) const
{
fseek(file, 0, SEEK_END);
@@ -565,7 +647,7 @@ bool BridgeManager::SendPitFile(FILE *file) const
if (!success)
{
- InterfaceManager::PrintError("Failed to request sending of PIT file!\n");
+ Interface::PrintError("Failed to request sending of PIT file!\n");
return (false);
}
@@ -575,7 +657,7 @@ bool BridgeManager::SendPitFile(FILE *file) const
if (!success)
{
- InterfaceManager::PrintError("Failed to confirm sending of PIT file!\n");
+ Interface::PrintError("Failed to confirm sending of PIT file!\n");
return (false);
}
@@ -586,7 +668,7 @@ bool BridgeManager::SendPitFile(FILE *file) const
if (!success)
{
- InterfaceManager::PrintError("Failed to send PIT file part information!\n");
+ Interface::PrintError("Failed to send PIT file part information!\n");
return (false);
}
@@ -596,7 +678,7 @@ bool BridgeManager::SendPitFile(FILE *file) const
if (!success)
{
- InterfaceManager::PrintError("Failed to confirm sending of PIT file part information!\n");
+ Interface::PrintError("Failed to confirm sending of PIT file part information!\n");
return (false);
}
@@ -607,7 +689,7 @@ bool BridgeManager::SendPitFile(FILE *file) const
if (!success)
{
- InterfaceManager::PrintError("Failed to send file part packet!\n");
+ Interface::PrintError("Failed to send file part packet!\n");
return (false);
}
@@ -617,7 +699,7 @@ bool BridgeManager::SendPitFile(FILE *file) const
if (!success)
{
- InterfaceManager::PrintError("Failed to receive PIT file transfer count!\n");
+ Interface::PrintError("Failed to receive PIT file transfer count!\n");
return (false);
}
@@ -637,7 +719,7 @@ int BridgeManager::ReceivePitFile(unsigned char **pitBuffer) const
if (!success)
{
- InterfaceManager::PrintError("Failed to request receival of PIT file!\n");
+ Interface::PrintError("Failed to request receival of PIT file!\n");
return (0);
}
@@ -648,7 +730,7 @@ int BridgeManager::ReceivePitFile(unsigned char **pitBuffer) const
if (!success)
{
- InterfaceManager::PrintError("Failed to receive PIT file size!\n");
+ Interface::PrintError("Failed to receive PIT file size!\n");
return (0);
}
@@ -668,7 +750,7 @@ int BridgeManager::ReceivePitFile(unsigned char **pitBuffer) const
if (!success)
{
- InterfaceManager::PrintError("Failed to request PIT file part #%i!\n", i);
+ Interface::PrintError("Failed to request PIT file part #%i!\n", i);
delete [] buffer;
return (0);
}
@@ -678,7 +760,7 @@ int BridgeManager::ReceivePitFile(unsigned char **pitBuffer) const
if (!success)
{
- InterfaceManager::PrintError("Failed to receive PIT file part #%i!\n", i);
+ Interface::PrintError("Failed to receive PIT file part #%i!\n", i);
delete receiveFilePartPacket;
delete [] buffer;
return (0);
@@ -698,7 +780,7 @@ int BridgeManager::ReceivePitFile(unsigned char **pitBuffer) const
if (!success)
{
- InterfaceManager::PrintError("Failed to send request to end PIT file transfer!\n");
+ Interface::PrintError("Failed to send request to end PIT file transfer!\n");
delete [] buffer;
return (0);
}
@@ -709,7 +791,7 @@ int BridgeManager::ReceivePitFile(unsigned char **pitBuffer) const
if (!success)
{
- InterfaceManager::PrintError("Failed to receive end PIT file transfer verification!\n");
+ Interface::PrintError("Failed to receive end PIT file transfer verification!\n");
delete [] buffer;
return (0);
}
@@ -722,13 +804,13 @@ bool BridgeManager::SendFile(FILE *file, int destination, int fileIdentifier) co
{
if (destination != EndFileTransferPacket::kDestinationModem && destination != EndFileTransferPacket::kDestinationPhone)
{
- InterfaceManager::PrintError("ERROR: Attempted to send file to unknown destination!\n");
+ Interface::PrintError("ERROR: Attempted to send file to unknown destination!\n");
return (false);
}
if (destination == EndFileTransferPacket::kDestinationModem && fileIdentifier != -1)
{
- InterfaceManager::PrintError("ERROR: The modem file does not have an identifier!\n");
+ Interface::PrintError("ERROR: The modem file does not have an identifier!\n");
return (false);
}
@@ -738,7 +820,7 @@ bool BridgeManager::SendFile(FILE *file, int destination, int fileIdentifier) co
if (!success)
{
- InterfaceManager::PrintError("Failed to initialise transfer!\n");
+ Interface::PrintError("Failed to initialise transfer!\n");
return (false);
}
@@ -752,7 +834,7 @@ bool BridgeManager::SendFile(FILE *file, int destination, int fileIdentifier) co
if (!success)
{
- InterfaceManager::PrintError("Failed to confirm transfer initialisation!\n");
+ Interface::PrintError("Failed to confirm transfer initialisation!\n");
return (false);
}
@@ -772,7 +854,7 @@ bool BridgeManager::SendFile(FILE *file, int destination, int fileIdentifier) co
long bytesTransferred = 0;
int currentPercent;
int previousPercent = 0;
- InterfaceManager::Print("0%%");
+ Interface::Print("0%%");
for (int sequenceIndex = 0; sequenceIndex < sequenceCount; sequenceIndex++)
{
@@ -786,7 +868,7 @@ bool BridgeManager::SendFile(FILE *file, int destination, int fileIdentifier) co
if (!success)
{
- InterfaceManager::PrintError("\nFailed to begin file transfer sequence!\n");
+ Interface::PrintError("\nFailed to begin file transfer sequence!\n");
return (false);
}
@@ -796,7 +878,7 @@ bool BridgeManager::SendFile(FILE *file, int destination, int fileIdentifier) co
if (!success)
{
- InterfaceManager::PrintError("\nFailed to confirm beginning of file transfer sequence!\n");
+ Interface::PrintError("\nFailed to confirm beginning of file transfer sequence!\n");
return (false);
}
@@ -812,7 +894,7 @@ bool BridgeManager::SendFile(FILE *file, int destination, int fileIdentifier) co
if (!success)
{
- InterfaceManager::PrintError("\nFailed to send file part packet!\n");
+ Interface::PrintError("\nFailed to send file part packet!\n");
return (false);
}
@@ -824,7 +906,7 @@ bool BridgeManager::SendFile(FILE *file, int destination, int fileIdentifier) co
if (verbose)
{
const unsigned char *data = sendFilePartResponse->GetData();
- InterfaceManager::Print("File Part #%i... Response: %X %X %X %X %X %X %X %X \n", filePartIndex,
+ Interface::Print("File Part #%i... Response: %X %X %X %X %X %X %X %X \n", filePartIndex,
data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]);
}
@@ -832,11 +914,11 @@ bool BridgeManager::SendFile(FILE *file, int destination, int fileIdentifier) co
if (!success)
{
- InterfaceManager::PrintError("\nFailed to receive file part response!\n");
+ Interface::PrintError("\nFailed to receive file part response!\n");
for (int retry = 0; retry < 4; retry++)
{
- InterfaceManager::PrintError("\nRetrying...");
+ Interface::PrintError("\nRetrying...");
// Send
sendFilePartPacket = new SendFilePartPacket(file);
@@ -845,7 +927,7 @@ bool BridgeManager::SendFile(FILE *file, int destination, int fileIdentifier) co
if (!success)
{
- InterfaceManager::PrintError("\nFailed to send file part packet!\n");
+ Interface::PrintError("\nFailed to send file part packet!\n");
return (false);
}
@@ -857,7 +939,7 @@ bool BridgeManager::SendFile(FILE *file, int destination, int fileIdentifier) co
if (verbose)
{
const unsigned char *data = sendFilePartResponse->GetData();
- InterfaceManager::Print("File Part #%i... Response: %X %X %X %X %X %X %X %X \n", filePartIndex,
+ Interface::Print("File Part #%i... Response: %X %X %X %X %X %X %X %X \n", filePartIndex,
data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]);
}
@@ -865,7 +947,7 @@ bool BridgeManager::SendFile(FILE *file, int destination, int fileIdentifier) co
if (receivedPartIndex != filePartIndex)
{
- InterfaceManager::PrintError("\nERROR: Expected file part index: %i Received: %i\n",
+ Interface::PrintError("\nERROR: Expected file part index: %i Received: %i\n",
filePartIndex, receivedPartIndex);
return (false);
}
@@ -880,7 +962,7 @@ bool BridgeManager::SendFile(FILE *file, int destination, int fileIdentifier) co
if (receivedPartIndex != filePartIndex)
{
- InterfaceManager::PrintError("\nERROR: Expected file part index: %i Received: %i\n",
+ Interface::PrintError("\nERROR: Expected file part index: %i Received: %i\n",
filePartIndex, receivedPartIndex);
return (false);
}
@@ -896,9 +978,9 @@ bool BridgeManager::SendFile(FILE *file, int destination, int fileIdentifier) co
if (currentPercent != previousPercent)
{
if (previousPercent < 10)
- InterfaceManager::Print("\b\b%i%%", currentPercent);
+ Interface::Print("\b\b%i%%", currentPercent);
else
- InterfaceManager::Print("\b\b\b%i%%", currentPercent);
+ Interface::Print("\b\b\b%i%%", currentPercent);
}
}
@@ -917,7 +999,7 @@ bool BridgeManager::SendFile(FILE *file, int destination, int fileIdentifier) co
if (!success)
{
- InterfaceManager::PrintError("\nFailed to end phone file transfer sequence!\n");
+ Interface::PrintError("\nFailed to end phone file transfer sequence!\n");
return (false);
}
}
@@ -931,7 +1013,7 @@ bool BridgeManager::SendFile(FILE *file, int destination, int fileIdentifier) co
if (!success)
{
- InterfaceManager::PrintError("\nFailed to end modem file transfer sequence!\n");
+ Interface::PrintError("\nFailed to end modem file transfer sequence!\n");
return (false);
}
}
@@ -942,13 +1024,13 @@ bool BridgeManager::SendFile(FILE *file, int destination, int fileIdentifier) co
if (!success)
{
- InterfaceManager::PrintError("\nFailed to confirm end of file transfer sequence!\n");
+ Interface::PrintError("\nFailed to confirm end of file transfer sequence!\n");
return (false);
}
}
if (!verbose)
- InterfaceManager::Print("\n");
+ Interface::Print("\n");
return (true);
}
@@ -964,7 +1046,7 @@ bool BridgeManager::ReceiveDump(int chipType, int chipId, FILE *file) const
if (!success)
{
- InterfaceManager::PrintError("Failed to request dump!\n");
+ Interface::PrintError("Failed to request dump!\n");
return (false);
}
@@ -975,7 +1057,7 @@ bool BridgeManager::ReceiveDump(int chipType, int chipId, FILE *file) const
if (!success)
{
- InterfaceManager::PrintError("Failed to receive dump size!\n");
+ Interface::PrintError("Failed to receive dump size!\n");
return (false);
}
@@ -994,7 +1076,7 @@ bool BridgeManager::ReceiveDump(int chipType, int chipId, FILE *file) const
if (!success)
{
- InterfaceManager::PrintError("Failed to request dump part #%i!\n", i);
+ Interface::PrintError("Failed to request dump part #%i!\n", i);
delete [] buffer;
return (false);
}
@@ -1004,7 +1086,7 @@ bool BridgeManager::ReceiveDump(int chipType, int chipId, FILE *file) const
if (!success)
{
- InterfaceManager::PrintError("Failed to receive dump part #%i!\n", i);
+ Interface::PrintError("Failed to receive dump part #%i!\n", i);
continue;
delete receiveFilePartPacket;
delete [] buffer;
@@ -1040,7 +1122,7 @@ bool BridgeManager::ReceiveDump(int chipType, int chipId, FILE *file) const
if (!success)
{
- InterfaceManager::PrintError("Failed to send request to end dump transfer!\n");
+ Interface::PrintError("Failed to send request to end dump transfer!\n");
return (false);
}
@@ -1050,34 +1132,7 @@ bool BridgeManager::ReceiveDump(int chipType, int chipId, FILE *file) const
if (!success)
{
- InterfaceManager::PrintError("Failed to receive end dump transfer verification!\n");
- return (false);
- }
-
- return (true);
-}
-
-bool BridgeManager::RebootDevice(void) const
-{
- InterfaceManager::Print("Rebooting device...\n");
-
- EndSessionPacket *rebootDevicePacket = new EndSessionPacket(EndSessionPacket::kRequestRebootDevice);
- bool success = SendPacket(rebootDevicePacket);
- delete rebootDevicePacket;
-
- if (!success)
- {
- InterfaceManager::PrintError("Failed to send reboot device packet!\n");
- return (false);
- }
-
- ResponsePacket *rebootDeviceResponse = new ResponsePacket(ResponsePacket::kResponseTypeEndSession);
- success = ReceivePacket(rebootDeviceResponse);
- delete rebootDeviceResponse;
-
- if (!success)
- {
- InterfaceManager::PrintError("Failed to receive reboot confirmation!\n");
+ Interface::PrintError("Failed to receive end dump transfer verification!\n");
return (false);
}
diff --git a/heimdall/source/BridgeManager.h b/heimdall/source/BridgeManager.h
index 06e4d61..c28cd9c 100644
--- a/heimdall/source/BridgeManager.h
+++ b/heimdall/source/BridgeManager.h
@@ -97,22 +97,23 @@ namespace Heimdall
BridgeManager(bool verbose, int communicationDelay);
~BridgeManager();
+ bool DetectDevice(void);
bool Initialise(void);
bool BeginSession(void) const;
- bool EndSession(void) const;
+ bool EndSession(bool reboot) const;
bool SendPacket(OutboundPacket *packet, int timeout = 3000) const;
bool ReceivePacket(InboundPacket *packet, int timeout = 3000) const;
+ bool RequestDeviceInfo(unsigned int request, int *result) const;
+
bool SendPitFile(FILE *file) const;
int ReceivePitFile(unsigned char **pitBuffer) const;
bool SendFile(FILE *file, int destination, int fileIdentifier = -1) const;
bool ReceiveDump(int chipType, int chipId, FILE *file) const;
- bool RebootDevice(void) const;
-
bool IsVerbose(void) const
{
return (verbose);
diff --git a/heimdall/source/Interface.cpp b/heimdall/source/Interface.cpp
new file mode 100644
index 0000000..5f0942d
--- /dev/null
+++ b/heimdall/source/Interface.cpp
@@ -0,0 +1,409 @@
+/* Copyright (c) 2010 Benjamin Dobell, Glass Echidna
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.*/
+
+// C/C++ Standard Library
+#include <cstdarg>
+#include <cstdlib>
+#include <stdio.h>
+
+// Heimdall
+#include "Heimdall.h"
+#include "Interface.h"
+
+using namespace std;
+using namespace libpit;
+using namespace Heimdall;
+
+const char *Interface::version = "v1.3.0";
+
+const char *Interface::usage = "Usage: heimdall <action> <arguments> [--verbose] [--no-reboot] [--delay <ms>]\n\
+\n\
+action: flash\n\
+arguments:\n\
+ --repartition --pit <filename> [--factoryfs <filename>]\n\
+ [--cache <filename>] [--dbdata <filename>] [--primary-boot <filename>]\n\
+ [--secondary-boot <filename>] [--param <filename>] [--kernel <filename>]\n\
+ [--modem <filename>] [--normal-boot <filename>] [--system <filename>]\n\
+ [--user-data <filename>] [--fota <filename>] [--hidden <filename>]\n\
+ [--movinand <filename>] [--data <filename>] [--ums <filename>]\n\
+ [--emmc <filename>] [--<partition identifier> <filename>]\n\
+ or:\n\
+ [--factoryfs <filename>] [--cache <filename>] [--dbdata <filename>]\n\
+ [--primary-boot <filename>] [--secondary-boot <filename>]\n\
+ [--secondary-boot-backup <filename>] [--param <filename>]\n\
+ [--kernel <filename>] [--recovery <filename>] [--efs <filename>]\n\
+ [--modem <filename>] [--normal-boot <filename>] [--system <filename>]\n\
+ [--user-data <filename>] [--fota <filename>] [--hidden <filename>]\n\
+ [--movinand <filename>] [--data <filename>] [--ums <filename>]\n\
+ [--emmc <filename>] [--<partition identifier> <filename>]\n\
+description: Flashes firmware files to your phone.\n\
+WARNING: If you're repartitioning it's strongly recommended you specify\n\
+ all files at your disposal, including bootloaders.\n\
+\n\
+action: close-pc-screen\n\
+description: Attempts to get rid off the \"connect phone to PC\" screen.\n\
+\n\
+action: detect\n\
+description: Indicates whether or not a download mode device can be detected.\n\
+\n\
+action: dump\n\
+arguments: --chip-type <NAND | RAM> --chip-id <integer> --output <filename>\n\
+description: Attempts to dump data from the phone corresponding to the\n\
+ specified chip type and chip ID.\n\
+NOTE: Galaxy S phones don't appear to properly support this functionality.\n\
+\n\
+action: print-pit\n\
+description: Dumps the PIT file from the connected device and prints it in\n\
+ a human readable format.\n\
+\n\
+action version\n\
+description: Displays the version number of this binary.\n\
+\n\
+action: help\n\
+description: Displays this dialogue.\n";
+
+const char *Interface::releaseInfo = "Heimdall %s, Copyright (c) 2010-2011, Benjamin Dobell, Glass Echidna\n\
+http://www.glassechidna.com.au\n\n\
+This software is provided free of charge. Copying and redistribution is\nencouraged.\n\n\
+If you appreciate this software and you would like to support future\ndevelopment please consider donating:\n\
+http://www.glassechidna.com.au/donate/\n\n";
+
+// Flash arguments
+string Interface::flashValueArguments[kFlashValueArgCount] = {
+ "-pit", "-factoryfs", "-cache", "-dbdata", "-primary-boot", "-secondary-boot", "-secondary-boot-backup", "-param", "-kernel", "-recovery", "-efs", "-modem",
+ "-normal-boot", "-system", "-user-data", "-fota", "-hidden", "-movinand", "-data", "-ums", "-emmc", "-%d"
+};
+
+string Interface::flashValueShortArguments[kFlashValueArgCount] = {
+ "pit", "fs", "cache", "db", "boot", "sbl", "sbl2", "param", "z", "rec", "efs", "m",
+ "norm", "sys", "udata", "fota", "hide", "nand", "data", "ums", "emmc", "%d"
+};
+
+string Interface::flashValuelessArguments[kFlashValuelessArgCount] = {
+ "-repartition"
+};
+
+string Interface::flashValuelessShortArguments[kFlashValuelessArgCount] = {
+ "r"
+};
+
+// Dump arguments
+string Interface::dumpValueArguments[kDumpValueArgCount] = {
+ "-chip-type", "-chip-id", "-output"
+};
+
+string Interface::dumpValueShortArguments[kDumpValueArgCount] = {
+ "type", "id", "out"
+};
+
+// Common arguments
+string Interface::commonValueArguments[kCommonValueArgCount] = {
+ "-delay"
+};
+
+string Interface::commonValueShortArguments[kCommonValueArgCount] = {
+ "d"
+};
+
+string Interface::commonValuelessArguments[kCommonValuelessArgCount] = {
+ "-verbose", "-no-reboot"
+};
+
+string Interface::commonValuelessShortArguments[kCommonValuelessArgCount] = {
+ "v", "nobt"
+};
+
+Action Interface::actions[Interface::kActionCount] = {
+ // kActionFlash
+ Action("flash", flashValueArguments, flashValueShortArguments, kFlashValueArgCount,
+ flashValuelessArguments, flashValuelessShortArguments, kFlashValuelessArgCount),
+
+ // kActionClosePcScreen
+ Action("close-pc-screen", nullptr, nullptr, kClosePcScreenValueArgCount,
+ nullptr, nullptr, kClosePcScreenValuelessArgCount),
+
+ // kActionDump
+ Action("dump", dumpValueArguments, dumpValueShortArguments, kDumpValueArgCount,
+ nullptr, nullptr, kDumpValuelessArgCount),
+
+ // kActionPrintPit
+ Action("print-pit", nullptr, nullptr, kPrintPitValueArgCount,
+ nullptr, nullptr, kPrintPitValuelessArgCount),
+
+ // kActionVersion
+ Action("version", nullptr, nullptr, kVersionValueArgCount,
+ nullptr, nullptr, kVersionValuelessArgCount),
+
+ // kActionHelp
+ Action("help", nullptr, nullptr, kHelpValueArgCount,
+ nullptr, nullptr, kHelpValuelessArgCount),
+
+ // kActionDetect
+ Action("detect", nullptr, nullptr, kDetectValueArgCount,
+ nullptr, nullptr, kDetectValuelessArgCount)
+};
+
+bool Interface::GetArguments(int argc, char **argv, map<string, string>& argumentMap, int *actionIndex)
+{
+ if (argc < 2)
+ {
+ Print(usage, version);
+ return (false);
+ }
+
+ const char *actionName = argv[1];
+ *actionIndex = -1;
+
+ for (int i = 0; i < kActionCount; i++)
+ {
+ if (actions[i].name == actionName)
+ {
+ *actionIndex = i;
+ break;
+ }
+ }
+
+ if (*actionIndex < 0)
+ {
+ Print("Unknown action \"%s\"\n\n", actionName);
+ Print(usage, version);
+ return (false);
+ }
+
+ const Action& action = actions[*actionIndex];
+
+ for (int argIndex = 2; argIndex < argc; argIndex++)
+ {
+ if (*(argv[argIndex]) != '-')
+ {
+ Print(usage, version);
+ return (false);
+ }
+
+ string argumentName = (char *)(argv[argIndex] + 1);
+
+ // Check if the argument is a valid valueless argument
+ bool valid = false;
+
+ for (unsigned int i = 0; i < action.valuelessArgumentCount; i++)
+ {
+ if (argumentName == action.valuelessArguments[i] || argumentName == action.valuelessShortArguments[i])
+ {
+ argumentName = action.valuelessArguments[i];
+ valid = true;
+ break;
+ }
+ }
+
+ if (!valid)
+ {
+ // Check if it's a common valueless argument
+ for (unsigned int i = 0; i < kCommonValuelessArgCount; i++)
+ {
+ if (argumentName == commonValuelessArguments[i] || argumentName == commonValuelessShortArguments[i])
+ {
+ argumentName = commonValuelessArguments[i];
+ valid = true;
+ break;
+ }
+ }
+ }
+
+ if (valid)
+ {
+ // The argument is valueless
+ argumentMap.insert(pair<string, string>(argumentName, ""));
+ continue;
+ }
+
+ // Check if the argument is a valid value argument
+ for (unsigned int i = 0; i < action.valueArgumentCount; i++)
+ {
+ // Support for --<integer> and -<integer> parameters.
+ if (argumentName.length() > 1 && action.valueArguments[i] == "-%d")
+ {
+ if (atoi(argumentName.substr(1).c_str()) > 0 || argumentName == "-0")
+ {
+ valid = true;
+ break;
+ }
+ }
+ else if (action.valueArguments[i] == "%d")
+ {
+ if (atoi(argumentName.c_str()) > 0 || argumentName == "0")
+ {
+ argumentName = "-" + argumentName;
+ valid = true;
+ break;
+ }
+ }
+
+ if (argumentName == action.valueArguments[i] || argumentName == action.valueShortArguments[i])
+ {
+ argumentName = action.valueArguments[i];
+ valid = true;
+ break;
+ }
+ }
+
+ if (!valid)
+ {
+ // Check if it's a common value argument
+ for (unsigned int i = 0; i < kCommonValueArgCount; i++)
+ {
+ // Support for --<integer> and -<integer> parameters.
+ if (argumentName.length() > 1 && commonValueArguments[i] == "-%d")
+ {
+ if (atoi(argumentName.substr(1).c_str()) > 0 || argumentName == "-0")
+ {
+ valid = true;
+ break;
+ }
+ }
+ else if (commonValueArguments[i] == "%d")
+ {
+ if (atoi(argumentName.c_str()) > 0 || argumentName == "0")
+ {
+ argumentName = "-" + argumentName;
+ valid = true;
+ break;
+ }
+ }
+
+ if (argumentName == commonValueArguments[i] || argumentName == commonValueShortArguments[i])
+ {
+ argumentName = commonValueArguments[i];
+ valid = true;
+ break;
+ }
+ }
+ }
+
+ if (!valid)
+ {
+ PrintError("\"%s\" is not a valid argument\n", argumentName.c_str());
+ return (false);
+ }
+
+ argIndex++;
+
+ if (argIndex >= argc)
+ {
+ PrintError("\"%s\" is missing a value\n", argumentName.c_str());
+ return (false);
+ }
+
+ argumentMap.insert(pair<string, string>(argumentName, argv[argIndex]));
+ }
+
+ return (true);
+}
+
+void Interface::Print(const char *format, ...)
+{
+ va_list args;
+
+ va_start(args, format);
+ vfprintf(stdout, format, args);
+ va_end(args);
+
+ fflush(stdout); // Make sure output isn't buffered.
+}
+
+void Interface::PrintError(const char *format, ...)
+{
+ va_list args;
+
+ va_start(args, format);
+ vfprintf(stderr, format, args);
+ va_end(args);
+
+ fflush(stderr); // Make sure output isn't buffered.
+}
+
+void Interface::PrintVersion(void)
+{
+ Print("%s\n", version);
+}
+
+void Interface::PrintUsage(void)
+{
+ Print(usage);
+}
+
+void Interface::PrintReleaseInfo(void)
+{
+ Print(releaseInfo, version);
+}
+
+void Interface::PrintPit(const PitData *pitData)
+{
+ Interface::Print("Entry Count: %d\n", pitData->GetEntryCount());
+
+ Interface::Print("Unknown 1: %d\n", pitData->GetUnknown1());
+ Interface::Print("Unknown 2: %d\n", pitData->GetUnknown2());
+ Interface::Print("Unknown 3: %d\n", pitData->GetUnknown3());
+ Interface::Print("Unknown 4: %d\n", pitData->GetUnknown4());
+ Interface::Print("Unknown 5: %d\n", pitData->GetUnknown5());
+ Interface::Print("Unknown 6: %d\n", pitData->GetUnknown6());
+ Interface::Print("Unknown 7: %d\n", pitData->GetUnknown7());
+ Interface::Print("Unknown 8: %d\n", pitData->GetUnknown8());
+
+ for (unsigned int i = 0; i < pitData->GetEntryCount(); i++)
+ {
+ const PitEntry *entry = pitData->GetEntry(i);
+
+ Interface::Print("\n\n--- Entry #%d ---\n", i);
+ Interface::Print("Unused: %s\n", (entry->GetUnused()) ? "Yes" : "No");
+
+ const char *partitionTypeText = "Unknown";
+
+ if (entry->GetPartitionType() == PitEntry::kPartitionTypeRfs)
+ partitionTypeText = "RFS";
+ else if (entry->GetPartitionType() == PitEntry::kPartitionTypeExt4)
+ partitionTypeText = "EXT4";
+
+ Interface::Print("Partition Type: %d (%s)\n", entry->GetPartitionType(), partitionTypeText);
+
+ Interface::Print("Partition Identifier: %d\n", entry->GetPartitionIdentifier());
+
+ Interface::Print("Partition Flags: %d (", entry->GetPartitionFlags());
+
+ if (entry->GetPartitionFlags() & PitEntry::kPartitionFlagWrite)
+ Interface::Print("R/W");
+ else
+ Interface::Print("R");
+
+ Interface::Print(")\n");
+
+ Interface::Print("Unknown 1: %d\n", entry->GetUnknown1());
+
+ Interface::Print("Partition Block Size: %d\n", entry->GetPartitionBlockSize());
+ Interface::Print("Partition Block Count: %d\n", entry->GetPartitionBlockCount());
+
+ Interface::Print("Unknown 2: %d\n", entry->GetUnknown2());
+ Interface::Print("Unknown 3: %d\n", entry->GetUnknown3());
+
+ Interface::Print("Partition Name: %s\n", entry->GetPartitionName());
+ Interface::Print("Filename: %s\n", entry->GetFilename());
+ }
+
+ Interface::Print("\n");
+}
diff --git a/heimdall/source/Interface.h b/heimdall/source/Interface.h
new file mode 100644
index 0000000..c6bdef3
--- /dev/null
+++ b/heimdall/source/Interface.h
@@ -0,0 +1,255 @@
+/* Copyright (c) 2010 Benjamin Dobell, Glass Echidna
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.*/
+
+#ifndef INTERFACE_H
+#define INTERFACE_H
+
+// C/C++ Standard Library
+#include <map>
+#include <string>
+
+// libpit
+#include "libpit.h"
+
+using namespace std;
+using namespace libpit;
+
+namespace Heimdall
+{
+ struct Action
+ {
+ public:
+
+ string name;
+
+ string *valueArguments;
+ string *valueShortArguments;
+ unsigned int valueArgumentCount;
+
+ string *valuelessArguments;
+ string *valuelessShortArguments;
+ unsigned int valuelessArgumentCount;
+
+ Action(const char *name, string *valueArguments, string *valueShortArguments, unsigned int valueArgumentCount,
+ string *valuelessArguments, string *valuelessShortArguments, unsigned int valuelessArgumentCount)
+ {
+ this->name = name;
+
+ this->valueArguments = valueArguments;
+ this->valueShortArguments = valueShortArguments;
+ this->valueArgumentCount = valueArgumentCount;
+
+ this->valuelessArguments = valuelessArguments;
+ this->valuelessShortArguments = valuelessShortArguments;
+ this->valuelessArgumentCount = valuelessArgumentCount;
+ }
+ };
+
+ class Interface
+ {
+ public:
+
+ // Actions
+ enum
+ {
+ kActionFlash = 0,
+ kActionClosePcScreen,
+ kActionDump,
+ kActionPrintPit,
+ kActionVersion,
+ kActionHelp,
+ kActionDetect,
+ kActionCount
+ };
+
+ // Flash value arguments
+ enum
+ {
+ kFlashValueArgPit,
+ kFlashValueArgFactoryFs,
+ kFlashValueArgCache,
+ kFlashValueArgDatabaseData,
+ kFlashValueArgPrimaryBootloader,
+ kFlashValueArgSecondaryBootloader,
+ kFlashValueArgSecondaryBootloaderBackup,
+ kFlashValueArgParam,
+ kFlashValueArgKernel,
+ kFlashValueArgRecovery,
+ kFlashValueArgEfs,
+ kFlashValueArgModem,
+
+ kFlashValueArgNormalBoot,
+ kFlashValueArgSystem,
+ kFlashValueArgUserData,
+ kFlashValueArgFota,
+ kFlashValueArgHidden,
+ kFlashValueArgMovinand,
+ kFlashValueArgData,
+ kFlashValueArgUms,
+ kFlashValueArgEmmc,
+
+ kFlashValueArgPartitionIndex,
+
+ kFlashValueArgCount
+ };
+
+ // Flash valueless arguments
+ enum
+ {
+ kFlashValuelessArgRepartition = 0,
+
+ kFlashValuelessArgCount
+ };
+
+ // Close PC Screen value arguments
+ enum
+ {
+ kClosePcScreenValueArgCount = 0
+ };
+
+ // Close PC Screen valueless arguments
+ enum
+ {
+ kClosePcScreenValuelessArgCount = 0
+ };
+
+ // Dump value arguments
+ enum
+ {
+ kDumpValueArgChipType = 0,
+ kDumpValueArgChipId,
+ kDumpValueArgOutput,
+
+ kDumpValueArgCount
+ };
+
+ // Dump valueless arguments
+ enum
+ {
+ kDumpValuelessArgCount = 0
+ };
+
+ // Print PIT value arguments
+ enum
+ {
+ kPrintPitValueArgCount = 0
+ };
+
+ // Print PIT valueless arguments
+ enum
+ {
+ kPrintPitValuelessArgCount = 0
+ };
+
+ // Version value arguments
+ enum
+ {
+ kVersionValueArgCount = 0
+ };
+
+ // Version valueless arguments
+ enum
+ {
+ kVersionValuelessArgCount = 0
+ };
+
+ // Help value arguments
+ enum
+ {
+ kHelpValueArgCount = 0
+ };
+
+ // Help valueless arguments
+ enum
+ {
+ kHelpValuelessArgCount = 0
+ };
+
+ // Detect value arguments
+ enum
+ {
+ kDetectValueArgCount = 0
+ };
+
+ // Detect valueless arguments
+ enum
+ {
+ kDetectValuelessArgCount = 0
+ };
+
+ // Common value arguments
+ enum
+ {
+ kCommonValueArgDelay = 0,
+
+ kCommonValueArgCount
+ };
+
+ // Comon valueless arguments
+ enum
+ {
+ kCommonValuelessArgVerbose = 0,
+ kCommonValuelessArgNoReboot,
+
+ kCommonValuelessArgCount
+ };
+
+ private:
+
+ static const char *version;
+ static const char *usage;
+ static const char *releaseInfo;
+
+ // Flash arguments
+ static string flashValueArguments[kFlashValueArgCount];
+ static string flashValueShortArguments[kFlashValueArgCount];
+
+ static string flashValuelessArguments[kFlashValuelessArgCount];
+ static string flashValuelessShortArguments[kFlashValuelessArgCount];
+
+ // Dump arguments
+ static string dumpValueArguments[kDumpValueArgCount];
+ static string dumpValueShortArguments[kDumpValueArgCount];
+
+ public:
+
+ // Common arguments
+ static string commonValueArguments[kCommonValueArgCount];
+ static string commonValueShortArguments[kCommonValueArgCount];
+
+ static string commonValuelessArguments[kCommonValuelessArgCount];
+ static string commonValuelessShortArguments[kCommonValuelessArgCount];
+
+ static Action actions[kActionCount];
+
+ static bool GetArguments(int argc, char **argv, map<string, string>& argumentMap, int *actionIndex);
+
+ static void Print(const char *format, ...);
+ static void PrintError(const char *format, ...);
+
+ static void PrintVersion(void);
+ static void PrintUsage(void);
+ static void PrintReleaseInfo(void);
+
+ static void PrintPit(const PitData *pitData);
+ };
+}
+
+#endif
diff --git a/heimdall/source/InterfaceManager.cpp b/heimdall/source/InterfaceManager.cpp
deleted file mode 100644
index 26ef028..0000000
--- a/heimdall/source/InterfaceManager.cpp
+++ /dev/null
@@ -1,325 +0,0 @@
-/* Copyright (c) 2010 Benjamin Dobell, Glass Echidna
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.*/
-
-// C/C++ Standard Library
-#include <cstdarg>
-#include <cstdlib>
-#include <stdio.h>
-
-// Heimdall
-#include "Heimdall.h"
-#include "InterfaceManager.h"
-
-using namespace std;
-using namespace Heimdall;
-
-string InterfaceManager::actionNames[kActionCount] = { "flash", "close-pc-screen", "dump", "print-pit", "help" };
-
-string InterfaceManager::flashArgumentNames[kFlashArgCount * 2] = {
- // --- Long Names ---
- "-repartition",
-
- "-pit", "-factoryfs", "-cache", "-dbdata", "-primary-boot", "-secondary-boot", "-secondary-boot-backup", "-param", "-kernel", "-recovery", "-efs", "-modem",
- "-normal-boot", "-system", "-user-data", "-fota", "-hidden", "-movinand", "-data", "-ums", "-emmc", "-%d",
-
- // --- Short Names ---
- "r",
-
- "pit", "fs", "cache", "db", "boot", "sbl", "sbl2", "param", "z", "rec", "efs", "m",
- "norm", "sys", "udata", "fota", "hide", "nand", "data", "ums", "emmc", "%d"
-};
-
-string InterfaceManager::dumpArgumentNames[kDumpArgCount * 2] = {
- // --- Long Names ---
- "-chip-type", "-chip-id", "-output",
-
- // --- Short Names ---
- "type", "id", "out"
-};
-
-string InterfaceManager::commonArgumentNames[kCommonArgCount * 2] = {
- // --- Long Names ---
- "-verbose", "-no-reboot",
-
- "-delay",
-
- // --- Short Names ---
- "v", "nobt",
-
- "d"
-};
-
-// argumentNames[kActionCount][] stores common arguments.
-string *InterfaceManager::actionArgumentNames[kActionCount + 1] = {
- // kActionFlash
- flashArgumentNames,
-
- // kActionClosePcScreen
- nullptr,
-
- // kActionDump
- dumpArgumentNames,
-
- // kActionPrintPit
- nullptr,
-
- // kActionHelp
- nullptr,
-
- // Common (kActionCount)
- commonArgumentNames
-};
-
-int InterfaceManager::actionArgumentCounts[kActionCount + 1] = {
- kFlashArgCount, 0, kDumpArgCount, 0, 0, kCommonArgCount
-};
-
-int InterfaceManager::actionValuelessArgumentCounts[kActionCount + 1] = {
- kFlashArgPit, 0, kDumpArgChipType, 0, 0, kCommonArgDelay
-};
-
-const char *InterfaceManager::usage = "\nHeimdall v1.2.0, Copyright (c) 2010-2011, Benjamin Dobell, Glass Echidna\n\n\
-Usage: heimdall <action> <arguments> [--verbose] [--no-reboot] [--delay <ms>]\n\
-\n\
-action: flash\n\
-arguments:\n\
- --repartition --pit <filename> [--factoryfs <filename>]\n\
- [--cache <filename>] [--dbdata <filename>] [--primary-boot <filename>]\n\
- [--secondary-boot <filename>] [--param <filename>] [--kernel <filename>]\n\
- [--modem <filename>] [--normal-boot <filename>] [--system <filename>]\n\
- [--user-data <filename>] [--fota <filename>] [--hidden <filename>]\n\
- [--movinand <filename>] [--data <filename>] [--ums <filename>]\n\
- [--emmc <filename>] [--<partition identifier> <filename>]\n\
- or:\n\
- [--factoryfs <filename>] [--cache <filename>] [--dbdata <filename>]\n\
- [--primary-boot <filename>] [--secondary-boot <filename>]\n\
- [--secondary-boot-backup <filename>] [--param <filename>]\n\
- [--kernel <filename>] [--recovery <filename>] [--efs <filename>]\n\
- [--modem <filename>] [--normal-boot <filename>] [--system <filename>]\n\
- [--user-data <filename>] [--fota <filename>] [--hidden <filename>]\n\
- [--movinand <filename>] [--data <filename>] [--ums <filename>]\n\
- [--emmc <filename>] [--<partition identifier> <filename>]\n\
-description: Flashes firmware files to your phone.\n\
-WARNING: If you're repartitioning it's strongly recommended you specify\n\
- all files at your disposal, including bootloaders.\n\
-\n\
-action: close-pc-screen\n\
-description: Attempts to get rid off the \"connect phone to PC\" screen.\n\
-\n\
-action: dump\n\
-arguments: --chip-type <NAND | RAM> --chip-id <integer> --output <filename>\n\
-description: Attempts to dump data from the phone corresponding to the\n\
- specified chip type and chip ID.\n\
-NOTE: Galaxy S phones don't appear to properly support this functionality.\n\
-\n\
-action: print-pit\n\
-description: Dumps the PIT file from the connected device and prints it in\n\
- a human readable format.\n\
-\n\
-action: help\n\
-description: Display this dialogue.\n";
-
-bool InterfaceManager::GetArguments(int argc, char **argv, map<string, string>& argumentMap, int *actionIndex)
-{
- if (argc < 2)
- {
- Print(usage);
- return (false);
- }
-
- const char *actionName = argv[1];
- *actionIndex = -1;
-
- for (int i = 0; i < kActionCount; i++)
- {
- if (actionNames[i] == actionName)
- {
- *actionIndex = i;
- break;
- }
- }
-
- if (*actionIndex < 0)
- {
- Print("Unknown action \"%s\"\n\n", actionName);
- Print(usage);
- return (false);
- }
-
- int actionArgumentCount = actionArgumentCounts[*actionIndex];
- int commonArgumentCount = actionArgumentCounts[kActionCount];
-
- int actionValuelessArgumentCount = actionValuelessArgumentCounts[*actionIndex];
- int commonValuelessArgumentCount = actionValuelessArgumentCounts[kActionCount];
-
- string *argumentNames = actionArgumentNames[*actionIndex];
- string *commonArgumentNames = actionArgumentNames[kActionCount];
-
- for (int argIndex = 2; argIndex < argc; argIndex++)
- {
- if (*(argv[argIndex]) != '-')
- {
- Print(usage);
- return (false);
- }
-
- string argumentName = (char *)(argv[argIndex] + 1);
-
- // Check if the argument is a valid valueless argument
- bool valid = false;
-
- for (int i = 0; i < actionValuelessArgumentCount; i++)
- {
- if (argumentName == argumentNames[i] || argumentName == argumentNames[actionArgumentCount + i])
- {
- argumentName = argumentNames[i];
- valid = true;
- break;
- }
- }
-
- if (!valid)
- {
- // Check if it's a common valueless argument
- for (int i = 0; i < commonValuelessArgumentCount; i++)
- {
- if (argumentName == commonArgumentNames[i] || argumentName == commonArgumentNames[commonArgumentCount + i])
- {
- argumentName = commonArgumentNames[i];
- valid = true;
- break;
- }
- }
- }
-
- if (valid)
- {
- // The argument is valueless
- argumentMap.insert(pair<string, string>(argumentName, ""));
- continue;
- }
-
- if (argumentNames != nullptr)
- {
- // Check if the argument is a valid regular argument
- for (int i = actionValuelessArgumentCount; i < actionArgumentCount; i++)
- {
- // Support for --<integer> and -<integer> parameters.
- if (argumentName.length() > 1 && argumentNames[i].compare("-%d") == 0)
- {
- if (atoi(argumentName.substr(1).c_str()) > 0 || argumentName.compare("-0") == 0)
- {
- valid = true;
- break;
- }
- }
- else if (argumentNames[i].compare("%d") == 0)
- {
- if (atoi(argumentName.c_str()) > 0 || argumentName.compare("0") == 0)
- {
- argumentName = "-" + argumentName;
- valid = true;
- break;
- }
- }
-
- if (argumentName == argumentNames[i] || argumentName == argumentNames[actionArgumentCount + i])
- {
- argumentName = argumentNames[i];
- valid = true;
- break;
- }
- }
- }
-
- if (!valid)
- {
- // Check if it's a common regular argument
- for (int i = commonValuelessArgumentCount; i < commonArgumentCount; i++)
- {
- // Support for --<integer> and -<integer> parameters.
- if (argumentName.length() > 1 && commonArgumentNames[i].compare("-%d"))
- {
- if (atoi(argumentName.substr(1).c_str()) > 0 || argumentName.compare("-0") == 0)
- {
- valid = true;
- break;
- }
- }
- else if (commonArgumentNames[i].compare("%d"))
- {
- if (atoi(argumentName.c_str()) > 0 || argumentName.compare("0") == 0)
- {
- argumentName = "-" + argumentName;
- valid = true;
- break;
- }
- }
-
- if (argumentName == commonArgumentNames[i] || argumentName == commonArgumentNames[commonArgumentCount + i])
- {
- argumentName = commonArgumentNames[i];
- valid = true;
- break;
- }
- }
- }
-
- if (!valid)
- {
- PrintError("\"%s\" is not a valid argument\n", argumentName.c_str());
- return (false);
- }
-
- argIndex++;
-
- if (argIndex >= argc)
- {
- PrintError("\"%s\" is missing a value\n", argumentName.c_str());
- return (false);
- }
-
- argumentMap.insert(pair<string, string>(argumentName, argv[argIndex]));
- }
-
- return (true);
-}
-
-void InterfaceManager::Print(const char *format, ...)
-{
- va_list args;
-
- va_start(args, format);
- vfprintf(stdout, format, args);
- va_end(args);
-
- fflush(stdout); // Make sure output isn't buffered.
-}
-
-void InterfaceManager::PrintError(const char *format, ...)
-{
- va_list args;
-
- va_start(args, format);
- vfprintf(stderr, format, args);
- va_end(args);
-
- fflush(stderr); // Make sure output isn't buffered.
-}
diff --git a/heimdall/source/InterfaceManager.h b/heimdall/source/InterfaceManager.h
deleted file mode 100644
index 1f5ba94..0000000
--- a/heimdall/source/InterfaceManager.h
+++ /dev/null
@@ -1,123 +0,0 @@
-/* Copyright (c) 2010 Benjamin Dobell, Glass Echidna
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.*/
-
-#ifndef INTERFACEMANAGER_H
-#define INTERFACEMANAGER_H
-
-// C/C++ Standard Library
-#include <map>
-#include <string>
-
-using namespace std;
-
-namespace Heimdall
-{
- class InterfaceManager
- {
- public:
-
- enum
- {
- kActionFlash = 0,
- kActionClosePcScreen,
- kActionDump,
- kActionPrintPit,
- kActionHelp,
- kActionCount
- };
-
- enum
- {
- // Valueless arguments
- kFlashArgRepartition = 0,
-
- // Regular arguments
- kFlashArgPit,
- kFlashArgFactoryFs,
- kFlashArgCache,
- kFlashArgDatabaseData,
- kFlashArgPrimaryBootloader,
- kFlashArgSecondaryBootloader,
- kFlashArgSecondaryBootloaderBackup,
- kFlashArgParam,
- kFlashArgKernel,
- kFlashArgRecovery,
- kFlashArgEfs,
- kFlashArgModem,
-
- kFlashArgNormalBoot,
- kFlashArgSystem,
- kFlashArgUserData,
- kFlashArgFota,
- kFlashArgHidden,
- kFlashArgMovinand,
- kFlashArgData,
- kFlashArgUms,
- kFlashArgEmmc,
-
- kFlashArgPartitionIndex,
-
- kFlashArgCount
- };
-
- enum
- {
- // Regular arguments
- kDumpArgChipType = 0,
- kDumpArgChipId,
- kDumpArgOutput,
-
- kDumpArgCount
- };
-
- enum
- {
- // Valueless arguments
- kCommonArgVerbose = 0,
- kCommonArgNoReboot,
-
- // Regular arguments
- kCommonArgDelay,
-
- kCommonArgCount
- };
-
- static string actionNames[kActionCount];
-
- static string flashArgumentNames[kFlashArgCount * 2];
- static string dumpArgumentNames[kDumpArgCount * 2];
- static string commonArgumentNames[kCommonArgCount * 2];
-
- // argumentNames[kActionCount][] defines common arguments.
- static string *actionArgumentNames[kActionCount + 1];
-
- static int actionArgumentCounts[kActionCount + 1];
- static int actionValuelessArgumentCounts[kActionCount + 1];
-
- static const char *usage;
-
- static bool GetArguments(int argc, char **argv, map<string, string>& argumentMap, int *actionIndex);
-
- static void Print(const char *format, ...);
- static void PrintError(const char *format, ...);
- };
-}
-
-#endif
diff --git a/heimdall/source/OutboundPacket.h b/heimdall/source/OutboundPacket.h
index dbe3f8a..8f8e6c6 100644
--- a/heimdall/source/OutboundPacket.h
+++ b/heimdall/source/OutboundPacket.h
@@ -21,7 +21,7 @@
#ifndef OUTBOUNDPACKET_H
#define OUTBOUNDPACKET_H
-// Heimdall include
+// Heimdall
#include "Packet.h"
namespace Heimdall
diff --git a/heimdall/source/PitData.cpp b/heimdall/source/PitData.cpp
deleted file mode 100755
index 10e88b7..0000000
--- a/heimdall/source/PitData.cpp
+++ /dev/null
@@ -1,284 +0,0 @@
-/* Copyright (c) 2010 Benjamin Dobell, Glass Echidna
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.*/
-
-// Heimdall
-#include "Heimdall.h"
-#include "InterfaceManager.h"
-#include "PitData.h"
-
-using namespace Heimdall;
-
-PitEntry::PitEntry()
-{
- unused = false;
- partitionType = 0;
- partitionIdentifier = 0;
- partitionFlags = 0;
- unknown2 = 0;
- partitionBlockSize = 0;
- partitionBlockCount = 0;
- unknown3 = 0;
- unknown4 = 0;
-
- memset(partitionName, 0, 32);
- memset(filename, 0, 64);
-}
-
-PitEntry::~PitEntry()
-{
-}
-
-void PitEntry::Print(void) const
-{
- InterfaceManager::Print("Unused: %s\n", (unused) ? "Yes" : "No");
-
- const char *partitionTypeText = "Unknown";
-
- if (partitionType == PitEntry::kPartitionTypeRfs)
- partitionTypeText = "RFS";
- else if (partitionType == PitEntry::kPartitionTypeExt4)
- partitionTypeText = "EXT4";
-
- InterfaceManager::Print("Partition Type: %d (%s)\n", partitionType, partitionTypeText);
-
- InterfaceManager::Print("Partition Identifier: %d\n", partitionIdentifier);
-
- InterfaceManager::Print("Partition Flags: %d (", partitionFlags);
-
- if (partitionFlags & PitEntry::kPartitionFlagWrite)
- InterfaceManager::Print("R/W");
- else
- InterfaceManager::Print("R");
-
- InterfaceManager::Print(")\n");
-
- InterfaceManager::Print("Unknown 2: %d\n", unknown2);
-
- InterfaceManager::Print("Partition Block Size: %d\n", partitionBlockSize);
- InterfaceManager::Print("Partition Block Count: %d\n", partitionBlockCount);
-
- InterfaceManager::Print("Unknown 3: %d\n", unknown3);
- InterfaceManager::Print("Unknown 4: %d\n", unknown4);
-
- InterfaceManager::Print("Partition Name: %s\n", partitionName);
- InterfaceManager::Print("Filename: %s\n", filename);
-}
-
-
-
-PitData::PitData()
-{
- entryCount = 0;
-
- unknown1 = 0;
- unknown2 = 0;
-
- unknown3 = 0;
- unknown4 = 0;
-
- unknown5 = 0;
- unknown6 = 0;
-
- unknown7 = 0;
- unknown8 = 0;
-}
-
-PitData::~PitData()
-{
- for (unsigned int i = 0; i < entries.size(); i++)
- delete entries[i];
-}
-
-bool PitData::Unpack(const unsigned char *data)
-{
- if (PitData::UnpackInteger(data, 0) != PitData::kFileIdentifier)
- return (false);
-
- // Remove existing entries
- for (unsigned int i = 0; i < entries.size(); i++)
- delete entries[i];
-
- entryCount = PitData::UnpackInteger(data, 4);
-
- entries.resize(entryCount);
-
- unknown1 = PitData::UnpackInteger(data, 8);
- unknown2 = PitData::UnpackInteger(data, 12);
-
- unknown3 = PitData::UnpackShort(data, 16);
- unknown4 = PitData::UnpackShort(data, 18);
-
- unknown5 = PitData::UnpackShort(data, 20);
- unknown6 = PitData::UnpackShort(data, 22);
-
- unknown7 = PitData::UnpackShort(data, 24);
- unknown8 = PitData::UnpackShort(data, 26);
-
- unsigned int integerValue;
- unsigned int entryOffset;
-
- for (unsigned int i = 0; i < entryCount; i++)
- {
- entryOffset = PitData::kHeaderDataSize + i * PitEntry::kDataSize;
-
- entries[i] = new PitEntry();
-
- integerValue = PitData::UnpackInteger(data, entryOffset);
- entries[i]->SetUnused((integerValue != 0) ? true : false);
-
- integerValue = PitData::UnpackInteger(data, entryOffset + 4);
- entries[i]->SetPartitionType(integerValue);
-
- integerValue = PitData::UnpackInteger(data, entryOffset + 8);
- entries[i]->SetPartitionIdentifier(integerValue);
-
- integerValue = PitData::UnpackInteger(data, entryOffset + 12);
- entries[i]->SetPartitionFlags(integerValue);
-
- integerValue = PitData::UnpackInteger(data, entryOffset + 16);
- entries[i]->SetUnknown2(integerValue);
-
- integerValue = PitData::UnpackInteger(data, entryOffset + 20);
- entries[i]->SetPartitionBlockSize(integerValue);
-
- integerValue = PitData::UnpackInteger(data, entryOffset + 24);
- entries[i]->SetPartitionBlockCount(integerValue);
-
- integerValue = PitData::UnpackInteger(data, entryOffset + 28);
- entries[i]->SetUnknown3(integerValue);
-
- integerValue = PitData::UnpackInteger(data, entryOffset + 32);
- entries[i]->SetUnknown4(integerValue);
-
- entries[i]->SetPartitionName((const char *)data + entryOffset + 36);
- entries[i]->SetFilename((const char *)data + entryOffset + 36 + PitEntry::kPartitionNameMaxLength);
- }
-
- return (true);
-}
-
-void PitData::Pack(unsigned char *data) const
-{
- PitData::PackInteger(data, 0, PitData::kFileIdentifier);
-
- PitData::PackInteger(data, 4, entryCount);
-
- PitData::PackInteger(data, 8, unknown1);
- PitData::PackInteger(data, 12, unknown2);
-
- PitData::PackShort(data, 16, unknown3);
- PitData::PackShort(data, 18, unknown4);
-
- PitData::PackShort(data, 20, unknown5);
- PitData::PackShort(data, 22, unknown6);
-
- PitData::PackShort(data, 24, unknown7);
- PitData::PackShort(data, 26, unknown8);
-
- int entryOffset;
-
- for (unsigned int i = 0; i < entryCount; i++)
- {
- entryOffset = PitData::kHeaderDataSize + i * PitEntry::kDataSize;
-
- PitData::PackInteger(data, entryOffset, (entries[i]->GetUnused()) ? 1 : 0);
-
- PitData::PackInteger(data, entryOffset + 4, entries[i]->GetPartitionType());
- PitData::PackInteger(data, entryOffset + 8, entries[i]->GetPartitionIdentifier());
- PitData::PackInteger(data, entryOffset + 12, entries[i]->GetPartitionFlags());
-
- PitData::PackInteger(data, entryOffset + 16, entries[i]->GetUnknown2());
-
- PitData::PackInteger(data, entryOffset + 20, entries[i]->GetPartitionBlockSize());
- PitData::PackInteger(data, entryOffset + 24, entries[i]->GetPartitionBlockCount());
-
- PitData::PackInteger(data, entryOffset + 28, entries[i]->GetUnknown3());
- PitData::PackInteger(data, entryOffset + 32, entries[i]->GetUnknown4());
-
- memcpy(data + entryOffset + 36, entries[i]->GetPartitionName(), PitEntry::kPartitionNameMaxLength);
- memcpy(data + entryOffset + 36 + PitEntry::kPartitionNameMaxLength, entries[i]->GetPartitionName(), PitEntry::kFilenameMaxLength);
- }
-}
-
-PitEntry *PitData::FindEntry(const char *partitionName)
-{
- for (unsigned int i = 0; i < entries.size(); i++)
- {
- if (strcmp(entries[i]->GetPartitionName(), partitionName) == 0)
- return (entries[i]);
- }
-
- return (nullptr);
-}
-
-const PitEntry *PitData::FindEntry(const char *partitionName) const
-{
- for (unsigned int i = 0; i < entries.size(); i++)
- {
- if (strcmp(entries[i]->GetPartitionName(), partitionName) == 0)
- return (entries[i]);
- }
-
- return (nullptr);
-}
-
-PitEntry *PitData::FindEntry(unsigned int partitionIdentifier)
-{
- for (unsigned int i = 0; i < entries.size(); i++)
- {
- if (entries[i]->GetPartitionIdentifier() == partitionIdentifier)
- return (entries[i]);
- }
-
- return (nullptr);
-}
-
-const PitEntry *PitData::FindEntry(unsigned int partitionIdentifier) const
-{
- for (unsigned int i = 0; i < entries.size(); i++)
- {
- if (entries[i]->GetPartitionIdentifier() == partitionIdentifier)
- return (entries[i]);
- }
-
- return (nullptr);
-}
-
-void PitData::Print(void) const
-{
- InterfaceManager::Print("Entry Count: %d\n", entryCount);
-
- InterfaceManager::Print("Unknown 1: %d\n", unknown1);
- InterfaceManager::Print("Unknown 2: %d\n", unknown2);
- InterfaceManager::Print("Unknown 3: %d\n", unknown3);
- InterfaceManager::Print("Unknown 4: %d\n", unknown4);
- InterfaceManager::Print("Unknown 5: %d\n", unknown5);
- InterfaceManager::Print("Unknown 6: %d\n", unknown6);
- InterfaceManager::Print("Unknown 7: %d\n", unknown7);
- InterfaceManager::Print("Unknown 8: %d\n", unknown8);
-
- for (unsigned int i = 0; i < entryCount; i++)
- {
- InterfaceManager::Print("\n\n--- Entry #%d ---\n", i);
- entries[i]->Print();
- }
-
- InterfaceManager::Print("\n");
-}
diff --git a/heimdall/source/PitData.h b/heimdall/source/PitData.h
deleted file mode 100755
index b6a0d2f..0000000
--- a/heimdall/source/PitData.h
+++ /dev/null
@@ -1,345 +0,0 @@
-/* Copyright (c) 2010 Benjamin Dobell, Glass Echidna
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.*/
-
-#ifndef PITDATA_H
-#define PITDATA_H
-
-// C Standard Library
-#include <string.h>
-#include <vector>
-
-namespace Heimdall
-{
- class PitEntry
- {
- public:
-
- enum
- {
- kDataSize = 132,
- kPartitionNameMaxLength = 32,
- kFilenameMaxLength = 64
- };
-
- enum
- {
- kPartitionTypeRfs = 0,
- kPartitionTypeBlank = 1, // ?
- kPartitionTypeExt4 = 2
- };
-
- enum
- {
- kPartitionFlagWrite = 1 << 1
- };
-
- private:
-
- bool unused;
-
- unsigned int partitionType;
- unsigned int partitionIdentifier;
- unsigned int partitionFlags;
-
- unsigned int unknown2;
-
- unsigned int partitionBlockSize;
- unsigned int partitionBlockCount;
-
- unsigned int unknown3;
- unsigned int unknown4;
-
- char partitionName[kPartitionNameMaxLength];
- char filename[kFilenameMaxLength];
-
- public:
-
- PitEntry();
- ~PitEntry();
-
- void Print(void) const;
-
- bool GetUnused(void) const
- {
- return unused;
- }
-
- void SetUnused(bool unused)
- {
- this->unused = unused;
- }
-
- unsigned int GetPartitionType(void) const
- {
- return partitionType;
- }
-
- void SetPartitionType(unsigned int partitionType)
- {
- this->partitionType = partitionType;
- }
-
- unsigned int GetPartitionIdentifier(void) const
- {
- return partitionIdentifier;
- }
-
- void SetPartitionIdentifier(unsigned int partitionIdentifier)
- {
- this->partitionIdentifier = partitionIdentifier;
- }
-
- unsigned int GetPartitionFlags(void) const
- {
- return partitionFlags;
- }
-
- void SetPartitionFlags(unsigned int partitionFlags)
- {
- this->partitionFlags = partitionFlags;
- }
-
- unsigned int GetUnknown2(void) const
- {
- return unknown2;
- }
-
- void SetUnknown2(unsigned int unknown2)
- {
- this->unknown2 = unknown2;
- }
-
- unsigned int GetPartitionBlockSize(void) const
- {
- return partitionBlockSize;
- }
-
- void SetPartitionBlockSize(unsigned int partitionBlockSize)
- {
- this->partitionBlockSize = partitionBlockSize;
- }
-
- unsigned int GetPartitionBlockCount(void) const
- {
- return partitionBlockCount;
- }
-
- void SetPartitionBlockCount(unsigned int partitionBlockCount)
- {
- this->partitionBlockCount = partitionBlockCount;
- }
-
- unsigned int GetUnknown3(void) const
- {
- return unknown3;
- }
-
- void SetUnknown3(unsigned int unknown3)
- {
- this->unknown3 = unknown3;
- }
-
- unsigned int GetUnknown4(void) const
- {
- return unknown4;
- }
-
- void SetUnknown4(unsigned int unknown4)
- {
- this->unknown4 = unknown4;
- }
-
- const char *GetPartitionName(void) const
- {
- return partitionName;
- }
-
- void SetPartitionName(const char *partitionName)
- {
- // This isn't strictly necessary but ensures no junk is left in our PIT file.
- memset(this->partitionName, 0, 64);
-
- if (strlen(partitionName) < 64)
- strcpy(this->partitionName, partitionName);
- else
- memcpy(this->partitionName, partitionName, 63);
- }
-
- const char *GetFilename(void) const
- {
- return filename;
- }
-
- void SetFilename(const char *filename)
- {
- // This isn't strictly necessary but ensures no junk is left in our PIT file.
- memset(this->filename, 0, 32);
-
- if (strlen(partitionName) < 32)
- strcpy(this->filename, filename);
- else
- memcpy(this->filename, filename, 31);
- }
- };
-
- class PitData
- {
- public:
-
- enum
- {
- kFileIdentifier = 0x12349876,
- kHeaderDataSize = 28
- };
-
- private:
-
- unsigned int entryCount; // 0x04
- unsigned int unknown1; // 0x08
- unsigned int unknown2; // 0x0C
-
- unsigned short unknown3; // 0x10 (7508 = I9000, 7703 = I9100 & P1000)?
- unsigned short unknown4; // 0x12 (Always 65, probably flags of some sort)
-
- unsigned short unknown5; // 0x14
- unsigned short unknown6; // 0x16
-
- unsigned short unknown7; // 0x18
- unsigned short unknown8; // 0x1A
-
- // Entries start at 0x1C
- std::vector<PitEntry *> entries;
-
- static int UnpackInteger(const unsigned char *data, unsigned int offset)
- {
-#ifdef WORDS_BIGENDIAN
- int value = (data[offset] << 24) | (data[offset + 1] << 16) |
- (data[offset + 2] << 8) | data[offset + 3];
-#else
- // Flip endianness
- int value = data[offset] | (data[offset + 1] << 8) |
- (data[offset + 2] << 16) | (data[offset + 3] << 24);
-#endif
- return (value);
- }
-
- static int UnpackShort(const unsigned char *data, unsigned int offset)
- {
-#ifdef WORDS_BIGENDIAN
- short value = (data[offset] << 8) | data[offset + 1];
-#else
- // Flip endianness
- short value = data[offset] | (data[offset + 1] << 8);
-#endif
- return (value);
- }
-
- static void PackInteger(unsigned char *data, unsigned int offset, unsigned int value)
- {
-#ifdef WORDS_BIGENDIAN
- data[offset] = (value & 0xFF000000) >> 24;
- data[offset + 1] = (value & 0x00FF0000) >> 16;
- data[offset + 2] = (value & 0x0000FF00) >> 8;
- data[offset + 3] = value & 0x000000FF;
-#else
- // Flip endianness
- data[offset] = value & 0x000000FF;
- data[offset + 1] = (value & 0x0000FF00) >> 8;
- data[offset + 2] = (value & 0x00FF0000) >> 16;
- data[offset + 3] = (value & 0xFF000000) >> 24;
-#endif
- }
-
- static void PackShort(unsigned char *data, unsigned int offset, unsigned short value)
- {
-#ifdef WORDS_BIGENDIAN
- data[offset] = (value & 0xFF00) >> 8;
- data[offset + 1] = value & 0x00FF;
-#else
- // Flip endianness
- data[offset] = value & 0x00FF;
- data[offset + 1] = (value & 0xFF00) >> 8;
-#endif
- }
-
- public:
-
- PitData();
- ~PitData();
-
- bool Unpack(const unsigned char *data);
- void Pack(unsigned char *data) const;
-
- PitEntry *FindEntry(const char *partitionName);
- const PitEntry *FindEntry(const char *partitionName) const;
-
- PitEntry *FindEntry(unsigned int partitionIdentifier);
- const PitEntry *FindEntry(unsigned int partitionIdentifier) const;
-
- void Print(void) const;
-
- unsigned int GetEntryCount(void) const
- {
- return entryCount;
- }
-
- unsigned int GetUnknown1(void) const
- {
- return unknown1;
- }
-
- unsigned int GetUnknown2(void) const
- {
- return unknown2;
- }
-
- unsigned short GetUnknown3(void) const
- {
- return unknown3;
- }
-
- unsigned short GetUnknown4(void) const
- {
- return unknown4;
- }
-
- unsigned short GetUnknown5(void) const
- {
- return unknown5;
- }
-
- unsigned short GetUnknown6(void) const
- {
- return unknown6;
- }
-
- unsigned short GetUnknown7(void) const
- {
- return unknown7;
- }
-
- unsigned short GetUnknown8(void) const
- {
- return unknown8;
- }
- };
-}
-
-#endif
diff --git a/heimdall/source/main.cpp b/heimdall/source/main.cpp
index 84260f0..64cc553 100644
--- a/heimdall/source/main.cpp
+++ b/heimdall/source/main.cpp
@@ -24,14 +24,16 @@
#include <stdio.h>
#include <string>
+// libpit
+#include "libpit.h"
+
// Heimdall
#include "BridgeManager.h"
#include "DeviceInfoPacket.h"
#include "DeviceInfoResponse.h"
#include "EndModemFileTransferPacket.h"
#include "EndPhoneFileTransferPacket.h"
-#include "InterfaceManager.h"
-#include "PitData.h"
+#include "Interface.h"
using namespace std;
using namespace Heimdall;
@@ -110,6 +112,26 @@ void initialiseKnownPartitionNames(void)
knownPartitionNames[kKnownPartitionEmmc].push_back("GANG");
}
+bool isKnownPartition(const char *partitionName, unsigned int knownPartitionIndex)
+{
+ for (unsigned int i = 0; i < knownPartitionNames[knownPartitionIndex].size(); i++)
+ {
+ if (strcmp(partitionName, knownPartitionNames[knownPartitionIndex][i]) == 0)
+ return (true);
+ }
+
+ return (false);
+}
+
+bool isKnownBootPartition(const char *partitionName)
+{
+ return (isKnownPartition(partitionName, kKnownPartitionPrimaryBootloader) ||
+ isKnownPartition(partitionName, kKnownPartitionSecondaryBootloader) ||
+ isKnownPartition(partitionName, kKnownPartitionSecondaryBootloaderBackup) ||
+ isKnownPartition(partitionName, kKnownPartitionParam) ||
+ isKnownPartition(partitionName, kKnownPartitionNormalBoot));
+}
+
bool openFiles(const map<string, string>& argumentMap, map<string, FILE *>& argumentFileMap)
{
map<string, string>::const_iterator it = argumentMap.begin();
@@ -130,7 +152,7 @@ bool openFiles(const map<string, string>& argumentMap, map<string, FILE *>& argu
// The argument wasn't a partition index, check if it's a known partition name.
for (int knownPartition = 0; knownPartition < kKnownPartitionCount; knownPartition++)
{
- if (it->first.compare(InterfaceManager::flashArgumentNames[InterfaceManager::kFlashArgPit + knownPartition]) == 0)
+ if (it->first == Interface::actions[Interface::kActionFlash].valueArguments[knownPartition])
{
isFileArgument = true;
break;
@@ -147,7 +169,7 @@ bool openFiles(const map<string, string>& argumentMap, map<string, FILE *>& argu
if (!argumentFilePair.second)
{
- InterfaceManager::PrintError("Failed to open file \"%s\"\n", it->second.c_str());
+ Interface::PrintError("Failed to open file \"%s\"\n", it->second.c_str());
return (false);
}
@@ -179,7 +201,7 @@ bool mapFilesToPartitions(const map<string, FILE *>& argumentFileMap, const PitD
for (knownPartition = 0; knownPartition < kKnownPartitionCount; knownPartition++)
{
- if (it->first.compare(InterfaceManager::flashArgumentNames[InterfaceManager::kFlashArgPit + knownPartition]) == 0)
+ if (it->first == Interface::actions[Interface::kActionFlash].valueArguments[knownPartition])
break;
}
@@ -195,7 +217,7 @@ bool mapFilesToPartitions(const map<string, FILE *>& argumentFileMap, const PitD
if (!pitEntry)
{
- InterfaceManager::PrintError("Partition corresponding to %s argument could not be located\n", it->first.c_str());
+ Interface::PrintError("Partition corresponding to %s argument could not be located\n", it->first.c_str());
return (false);
}
@@ -216,18 +238,18 @@ void closeFiles(map<string, FILE *> argumentfileMap)
int downloadPitFile(BridgeManager *bridgeManager, unsigned char **pitBuffer)
{
- InterfaceManager::Print("Downloading device's PIT file...\n");
+ Interface::Print("Downloading device's PIT file...\n");
int devicePitFileSize = bridgeManager->ReceivePitFile(pitBuffer);
if (!*pitBuffer)
{
- InterfaceManager::PrintError("Failed to download PIT file!\n");
+ Interface::PrintError("Failed to download PIT file!\n");
return (-1);
}
- InterfaceManager::Print("PIT file download sucessful\n\n");
+ Interface::Print("PIT file download sucessful\n\n");
return devicePitFileSize;
}
@@ -247,16 +269,16 @@ bool flashFile(BridgeManager *bridgeManager, unsigned int partitionIndex, const
if (isPit)
{
- InterfaceManager::Print("Uploading %s\n", partitionName);
+ Interface::Print("Uploading %s\n", partitionName);
if (bridgeManager->SendPitFile(file))
{
- InterfaceManager::Print("%s upload successful\n", partitionName);
+ Interface::Print("%s upload successful\n", partitionName);
return (true);
}
else
{
- InterfaceManager::PrintError("%s upload failed!\n", partitionName);
+ Interface::PrintError("%s upload failed!\n", partitionName);
return (false);
}
}
@@ -276,34 +298,34 @@ bool flashFile(BridgeManager *bridgeManager, unsigned int partitionIndex, const
if (isModem)
{
- InterfaceManager::Print("Uploading %s\n", partitionName);
+ Interface::Print("Uploading %s\n", partitionName);
//if (bridgeManager->SendFile(file, EndPhoneFileTransferPacket::kDestinationPhone, // <-- Kies method. WARNING: Doesn't work on Galaxy Tab!
// EndPhoneFileTransferPacket::kFileModem))
if (bridgeManager->SendFile(file, EndModemFileTransferPacket::kDestinationModem)) // <-- Odin method
{
- InterfaceManager::Print("%s upload successful\n", partitionName);
+ Interface::Print("%s upload successful\n", partitionName);
return (true);
}
else
{
- InterfaceManager::PrintError("%s upload failed!\n", partitionName);
+ Interface::PrintError("%s upload failed!\n", partitionName);
return (false);
}
}
else
{
// We're uploading to a phone partition
- InterfaceManager::Print("Uploading %s\n", partitionName);
+ Interface::Print("Uploading %s\n", partitionName);
if (bridgeManager->SendFile(file, EndPhoneFileTransferPacket::kDestinationPhone, partitionIndex))
{
- InterfaceManager::Print("%s upload successful\n", partitionName);
+ Interface::Print("%s upload successful\n", partitionName);
return (true);
}
else
{
- InterfaceManager::PrintError("%s upload failed!\n", partitionName);
+ Interface::PrintError("%s upload failed!\n", partitionName);
return (false);
}
}
@@ -318,63 +340,31 @@ bool attemptFlash(BridgeManager *bridgeManager, map<string, FILE *> argumentFile
// ---------- GET DEVICE INFORMATION ----------
- DeviceInfoPacket *deviceInfoPacket = new DeviceInfoPacket(DeviceInfoPacket::kUnknown1);
- success = bridgeManager->SendPacket(deviceInfoPacket);
- delete deviceInfoPacket;
-
- if (!success)
- {
- InterfaceManager::PrintError("Failed to send device info packet!\nFailed Request: kUnknown1\n");
- return (false);
- }
-
- DeviceInfoResponse *deviceInfoResponse = new DeviceInfoResponse();
- success = bridgeManager->ReceivePacket(deviceInfoResponse);
- int unknown = deviceInfoResponse->GetUnknown();
- delete deviceInfoResponse;
-
- if (!success)
- {
- InterfaceManager::PrintError("Failed to receive device info response!\n");
+ int deviceInfoResult;
+
+ if (!bridgeManager->RequestDeviceInfo(DeviceInfoPacket::kUnknown1, &deviceInfoResult))
return (false);
- }
// 131072 for Galaxy S II, 0 for other devices.
- if (unknown != 0 && unknown != 131072)
+ if (deviceInfoResult != 0 && deviceInfoResult != 131072)
{
- InterfaceManager::PrintError("Unexpected device info response!\nExpected: 0\nReceived:%i\n", unknown);
+ Interface::PrintError("Unexpected device info response!\nExpected: 0\nReceived:%i\n", deviceInfoResult);
return (false);
}
// -------------------- KIES DOESN'T DO THIS --------------------
- deviceInfoPacket = new DeviceInfoPacket(DeviceInfoPacket::kUnknown2);
- success = bridgeManager->SendPacket(deviceInfoPacket);
- delete deviceInfoPacket;
- if (!success)
- {
- InterfaceManager::PrintError("Failed to send device info packet!\nFailed Request: kUnknown2\n");
+ if (!bridgeManager->RequestDeviceInfo(DeviceInfoPacket::kUnknown2, &deviceInfoResult))
return (false);
- }
-
- deviceInfoResponse = new DeviceInfoResponse();
- success = bridgeManager->ReceivePacket(deviceInfoResponse);
- unknown = deviceInfoResponse->GetUnknown();
- delete deviceInfoResponse;
-
- if (!success)
- {
- InterfaceManager::PrintError("Failed to receive device info response!\n");
- return (false);
- }
// TODO: Work out what this value is... it has been either 180 or 0 for Galaxy S phones, 3 on the Galaxy Tab, 190 for SHW-M110S.
- if (unknown != 180 && unknown != 0 && unknown != 3 && unknown != 190)
+ if (deviceInfoResult != 180 && deviceInfoResult != 0 && deviceInfoResult != 3 && deviceInfoResult != 190)
{
- InterfaceManager::PrintError("Unexpected device info response!\nExpected: 180, 0 or 3\nReceived:%i\n", unknown);
+ Interface::PrintError("Unexpected device info response!\nExpected: 180, 0 or 3\nReceived:%i\n", deviceInfoResult);
return (false);
}
- // --------------------------------------------------------------
+
+ // ------------- SEND TOTAL BYTES TO BE TRANSFERRED -------------
int totalBytes = 0;
for (map<string, FILE *>::const_iterator it = argumentFileMap.begin(); it != argumentFileMap.end(); it++)
@@ -384,30 +374,30 @@ bool attemptFlash(BridgeManager *bridgeManager, map<string, FILE *> argumentFile
rewind(it->second);
}
- deviceInfoPacket = new DeviceInfoPacket(DeviceInfoPacket::kTotalBytes, totalBytes);
+ DeviceInfoPacket *deviceInfoPacket = new DeviceInfoPacket(DeviceInfoPacket::kTotalBytes, totalBytes);
success = bridgeManager->SendPacket(deviceInfoPacket);
delete deviceInfoPacket;
if (!success)
{
- InterfaceManager::PrintError("Failed to send total bytes device info packet!\n");
+ Interface::PrintError("Failed to send total bytes device info packet!\n");
return (false);
}
- deviceInfoResponse = new DeviceInfoResponse();
+ DeviceInfoResponse *deviceInfoResponse = new DeviceInfoResponse();
success = bridgeManager->ReceivePacket(deviceInfoResponse);
- unknown = deviceInfoResponse->GetUnknown();
+ deviceInfoResult = deviceInfoResponse->GetUnknown();
delete deviceInfoResponse;
if (!success)
{
- InterfaceManager::PrintError("Failed to receive device info response!\n");
+ Interface::PrintError("Failed to receive device info response!\n");
return (false);
}
- if (unknown != 0)
+ if (deviceInfoResult != 0)
{
- InterfaceManager::PrintError("Unexpected device info response!\nExpected: 0\nReceived:%i\n", unknown);
+ Interface::PrintError("Unexpected device info response!\nExpected: 0\nReceived:%i\n", deviceInfoResult);
return (false);
}
@@ -419,13 +409,12 @@ bool attemptFlash(BridgeManager *bridgeManager, map<string, FILE *> argumentFile
if (repartition)
{
// If we're repartitioning then we need to unpack the information from the specified PIT file.
-
- map<string, FILE *>::iterator it = argumentFileMap.find(InterfaceManager::flashArgumentNames[InterfaceManager::kFlashArgPit]);
+ map<string, FILE *>::iterator it = argumentFileMap.find(Interface::actions[Interface::kActionFlash].valueArguments[Interface::kFlashValueArgPit]);
// This shouldn't ever happen due to early checks, but we'll check again just in case...
if (it == argumentFileMap.end())
{
- InterfaceManager::PrintError("Attempt was made to repartition without specifying a PIT file!\n");
+ Interface::PrintError("Attempt was made to repartition without specifying a PIT file!\n");
return (false);
}
@@ -451,7 +440,6 @@ bool attemptFlash(BridgeManager *bridgeManager, map<string, FILE *> argumentFile
else
{
// If we're not repartitioning then we need to retrieve the device's PIT file and unpack it.
-
unsigned char *pitFileBuffer;
downloadPitFile(bridgeManager, &pitFileBuffer);
@@ -463,9 +451,13 @@ bool attemptFlash(BridgeManager *bridgeManager, map<string, FILE *> argumentFile
map<unsigned int, PartitionNameFilePair> partitionFileMap;
- // Map the files being flashed to partitions stored in PIT file.
- mapFilesToPartitions(argumentFileMap, pitData, partitionFileMap);
-
+ // Map the files being flashed to partitions stored in the PIT file.
+ if (!mapFilesToPartitions(argumentFileMap, pitData, partitionFileMap))
+ {
+ delete pitData;
+ return (false);
+ }
+
delete pitData;
// If we're repartitioning then we need to flash the PIT file first.
@@ -477,14 +469,26 @@ bool attemptFlash(BridgeManager *bridgeManager, map<string, FILE *> argumentFile
{
if (!flashFile(bridgeManager, it->first, it->second.partitionName.c_str(), it->second.file))
return (false);
+
+ break;
}
}
}
- // Flash all other files
+ // Flash partitions not involved in the boot process second.
for (map<unsigned int, PartitionNameFilePair>::iterator it = partitionFileMap.begin(); it != partitionFileMap.end(); it++)
{
- if (it->second.file != localPitFile)
+ if (!isKnownPartition(it->second.partitionName.c_str(), kKnownPartitionPit) && !isKnownBootPartition(it->second.partitionName.c_str()))
+ {
+ if (!flashFile(bridgeManager, it->first, it->second.partitionName.c_str(), it->second.file))
+ return (false);
+ }
+ }
+
+ // Flash boot partitions last.
+ for (map<unsigned int, PartitionNameFilePair>::iterator it = partitionFileMap.begin(); it != partitionFileMap.end(); it++)
+ {
+ if (isKnownBootPartition(it->second.partitionName.c_str()))
{
if (!flashFile(bridgeManager, it->first, it->second.partitionName.c_str(), it->second.file))
return (false);
@@ -499,7 +503,7 @@ int main(int argc, char **argv)
map<string, string> argumentMap;
int actionIndex;
- if (!InterfaceManager::GetArguments(argc, argv, argumentMap, &actionIndex))
+ if (!Interface::GetArguments(argc, argv, argumentMap, &actionIndex))
{
Sleep(250);
return (0);
@@ -507,83 +511,95 @@ int main(int argc, char **argv)
initialiseKnownPartitionNames();
- if (actionIndex == InterfaceManager::kActionHelp)
- {
- InterfaceManager::Print(InterfaceManager::usage);
- return (0);
- }
- else if (actionIndex == InterfaceManager::kActionFlash)
+ switch (actionIndex)
{
- if (argumentMap.find(InterfaceManager::flashArgumentNames[InterfaceManager::kFlashArgRepartition]) != argumentMap.end()
- && argumentMap.find(InterfaceManager::flashArgumentNames[InterfaceManager::kFlashArgPit]) == argumentMap.end())
- {
- InterfaceManager::Print("If you wish to repartition then a PIT file must be specified.\n");
- return (0);
- }
+ case Interface::kActionFlash:
+ if (argumentMap.find(Interface::actions[Interface::kActionFlash].valuelessArguments[Interface::kFlashValuelessArgRepartition]) != argumentMap.end()
+ && argumentMap.find(Interface::actions[Interface::kActionFlash].valueArguments[Interface::kFlashValueArgPit]) == argumentMap.end())
+ {
+ Interface::Print("If you wish to repartition then a PIT file must be specified.\n");
+ return (0);
+ }
- if (argumentMap.find(InterfaceManager::flashArgumentNames[InterfaceManager::kFlashArgPit]) != argumentMap.end()
- && argumentMap.find(InterfaceManager::flashArgumentNames[InterfaceManager::kFlashArgRepartition]) == argumentMap.end())
- {
- InterfaceManager::Print("A PIT file should only be used when repartitioning.\n");
- return (0);
- }
- }
- else if (actionIndex == InterfaceManager::kActionDump)
- {
- if (argumentMap.find(InterfaceManager::dumpArgumentNames[InterfaceManager::kDumpArgOutput]) == argumentMap.end())
- {
- InterfaceManager::Print("Output file not specified.\n\n");
- InterfaceManager::Print(InterfaceManager::usage);
- return (0);
- }
+ if (argumentMap.find(Interface::actions[Interface::kActionFlash].valueArguments[Interface::kFlashValueArgPit]) != argumentMap.end()
+ && argumentMap.find(Interface::actions[Interface::kActionFlash].valuelessArguments[Interface::kFlashValuelessArgRepartition]) == argumentMap.end())
+ {
+ Interface::Print("A PIT file should only be used when repartitioning.\n");
+ return (0);
+ }
- if (argumentMap.find(InterfaceManager::dumpArgumentNames[InterfaceManager::kDumpArgChipType]) == argumentMap.end())
- {
- InterfaceManager::Print("You must specify a chip type.\n\n");
- InterfaceManager::Print(InterfaceManager::usage);
- return (0);
- }
+ break;
- string chipType = argumentMap.find(InterfaceManager::dumpArgumentNames[InterfaceManager::kDumpArgChipType])->second;
- if (!(chipType == "RAM" || chipType == "ram" || chipType == "NAND" || chipType == "nand"))
+ case Interface::kActionDump:
{
- InterfaceManager::Print("Unknown chip type: %s.\n\n", chipType.c_str());
- InterfaceManager::Print(InterfaceManager::usage);
- return (0);
+ if (argumentMap.find(Interface::actions[Interface::kActionDump].valueArguments[Interface::kDumpValueArgOutput]) == argumentMap.end())
+ {
+ Interface::Print("Output file not specified.\n\n");
+ Interface::PrintUsage();
+ return (0);
+ }
+
+ if (argumentMap.find(Interface::actions[Interface::kActionDump].valueArguments[Interface::kDumpValueArgChipType]) == argumentMap.end())
+ {
+ Interface::Print("You must specify a chip type.\n\n");
+ Interface::PrintUsage();
+ return (0);
+ }
+
+ string chipType = argumentMap.find(Interface::actions[Interface::kActionDump].valueArguments[Interface::kDumpValueArgChipType])->second;
+ if (!(chipType == "RAM" || chipType == "ram" || chipType == "NAND" || chipType == "nand"))
+ {
+ Interface::Print("Unknown chip type: %s.\n\n", chipType.c_str());
+ Interface::PrintUsage();
+ return (0);
+ }
+
+ if (argumentMap.find(Interface::actions[Interface::kActionDump].valueArguments[Interface::kDumpValueArgChipId]) == argumentMap.end())
+ {
+ Interface::Print("You must specify a Chip ID.\n\n");
+ Interface::PrintUsage();
+ return (0);
+ }
+
+ int chipId = atoi(argumentMap.find(Interface::actions[Interface::kActionDump].valueArguments[Interface::kDumpValueArgChipId])->second.c_str());
+ if (chipId < 0)
+ {
+ Interface::Print("Chip ID must be a non-negative integer.\n");
+ return (0);
+ }
+
+ break;
}
- if (argumentMap.find(InterfaceManager::dumpArgumentNames[InterfaceManager::kDumpArgChipId]) == argumentMap.end())
- {
- InterfaceManager::Print("You must specify a Chip ID.\n\n");
- InterfaceManager::Print(InterfaceManager::usage);
+ case Interface::kActionVersion:
+ Interface::PrintVersion();
return (0);
- }
- int chipId = atoi(argumentMap.find(InterfaceManager::dumpArgumentNames[InterfaceManager::kDumpArgChipId])->second.c_str());
- if (chipId < 0)
- {
- InterfaceManager::Print("Chip ID must be a non-negative integer.\n");
+ case Interface::kActionHelp:
+ Interface::PrintUsage();
return (0);
- }
}
- InterfaceManager::Print("\nHeimdall v1.2.0, Copyright (c) 2010-2011, Benjamin Dobell, Glass Echidna\n");
- InterfaceManager::Print("http://www.glassechidna.com.au\n\n");
- InterfaceManager::Print("This software is provided free of charge. Copying and redistribution is\nencouraged.\n\n");
- InterfaceManager::Print("If you appreciate this software and you would like to support future\ndevelopment please consider donating:\n");
- InterfaceManager::Print("http://www.glassechidna.com.au/donate/\n\n");
-
- Sleep(1000);
-
- bool verbose = argumentMap.find(InterfaceManager::commonArgumentNames[InterfaceManager::kCommonArgVerbose]) != argumentMap.end();
- bool noReboot = argumentMap.find(InterfaceManager::commonArgumentNames[InterfaceManager::kCommonArgNoReboot]) != argumentMap.end();
+ bool verbose = argumentMap.find(Interface::commonValuelessArguments[Interface::kCommonValuelessArgVerbose]) != argumentMap.end();
+ bool reboot = argumentMap.find(Interface::commonValuelessArguments[Interface::kCommonValuelessArgNoReboot]) == argumentMap.end();
int communicationDelay = BridgeManager::kCommunicationDelayDefault;
- if (argumentMap.find(InterfaceManager::commonArgumentNames[InterfaceManager::kCommonArgDelay]) != argumentMap.end())
- communicationDelay = atoi(argumentMap.find(InterfaceManager::commonArgumentNames[InterfaceManager::kCommonArgDelay])->second.c_str());
+ if (argumentMap.find(Interface::commonValueArguments[Interface::kCommonValueArgDelay]) != argumentMap.end())
+ communicationDelay = atoi(argumentMap.find(Interface::commonValueArguments[Interface::kCommonValueArgDelay])->second.c_str());
BridgeManager *bridgeManager = new BridgeManager(verbose, communicationDelay);
+ if (actionIndex == Interface::kActionDetect)
+ {
+ bridgeManager->DetectDevice();
+
+ delete bridgeManager;
+ return (0);
+ }
+
+ Interface::PrintReleaseInfo();
+ Sleep(1000);
+
if (!bridgeManager->Initialise())
{
delete bridgeManager;
@@ -594,7 +610,7 @@ int main(int argc, char **argv)
switch (actionIndex)
{
- case InterfaceManager::kActionFlash:
+ case Interface::kActionFlash:
{
map<string, FILE *> argumentFileMap;
@@ -615,20 +631,17 @@ int main(int argc, char **argv)
return (-1);
}
- bool repartition = argumentMap.find(InterfaceManager::flashArgumentNames[InterfaceManager::kFlashArgRepartition]) != argumentMap.end();
+ bool repartition = argumentMap.find(Interface::actions[Interface::kActionFlash].valuelessArguments[Interface::kFlashValuelessArgRepartition]) != argumentMap.end();
success = attemptFlash(bridgeManager, argumentFileMap, repartition);
- if (noReboot)
- success = bridgeManager->EndSession() && success;
- else
- success = bridgeManager->EndSession() && bridgeManager->RebootDevice() && success;
+ success = bridgeManager->EndSession(reboot) && success;
closeFiles(argumentFileMap);
break;
}
- case InterfaceManager::kActionClosePcScreen:
+ case Interface::kActionClosePcScreen:
{
if (!bridgeManager->BeginSession())
{
@@ -636,37 +649,34 @@ int main(int argc, char **argv)
return (-1);
}
- InterfaceManager::Print("Attempting to close connect to pc screen...\n");
+ Interface::Print("Attempting to close connect to pc screen...\n");
- if (noReboot)
- success = bridgeManager->EndSession();
- else
- success = bridgeManager->EndSession() && bridgeManager->RebootDevice();
+ success = bridgeManager->EndSession(reboot);
if (success)
- InterfaceManager::Print("Attempt complete\n");
+ Interface::Print("Attempt complete\n");
break;
}
- case InterfaceManager::kActionDump:
+ case Interface::kActionDump:
{
- const char *outputFilename = argumentMap.find(InterfaceManager::dumpArgumentNames[InterfaceManager::kDumpArgOutput])->second.c_str();
+ const char *outputFilename = argumentMap.find(Interface::actions[Interface::kActionDump].valueArguments[Interface::kDumpValueArgOutput])->second.c_str();
FILE *dumpFile = fopen(outputFilename, "wb");
if (!dumpFile)
{
- InterfaceManager::PrintError("Failed to open file \"%s\"\n", outputFilename);
+ Interface::PrintError("Failed to open file \"%s\"\n", outputFilename);
delete bridgeManager;
return (-1);
}
int chipType = 0;
- string chipTypeName = argumentMap.find(InterfaceManager::dumpArgumentNames[InterfaceManager::kDumpArgChipType])->second;
+ string chipTypeName = argumentMap.find(Interface::actions[Interface::kActionDump].valueArguments[Interface::kDumpValueArgChipType])->second;
if (chipTypeName == "NAND" || chipTypeName == "nand")
chipType = 1;
- int chipId = atoi(argumentMap.find(InterfaceManager::dumpArgumentNames[InterfaceManager::kDumpArgChipId])->second.c_str());
+ int chipId = atoi(argumentMap.find(Interface::actions[Interface::kActionDump].valueArguments[Interface::kDumpValueArgChipId])->second.c_str());
if (!bridgeManager->BeginSession())
{
@@ -680,15 +690,12 @@ int main(int argc, char **argv)
fclose(dumpFile);
- if (noReboot)
- success = bridgeManager->EndSession() && success;
- else
- success = bridgeManager->EndSession() && bridgeManager->RebootDevice() && success;
+ success = bridgeManager->EndSession(reboot) && success;
break;
}
- case InterfaceManager::kActionPrintPit:
+ case Interface::kActionPrintPit:
{
if (!bridgeManager->BeginSession())
{
@@ -700,11 +707,7 @@ int main(int argc, char **argv)
if (downloadPitFile(bridgeManager, &devicePit) < -1)
{
- if (!bridgeManager->EndSession())
- return (-1);
-
- if (!noReboot)
- bridgeManager->RebootDevice();
+ bridgeManager->EndSession(reboot);
delete bridgeManager;
return (-1);
@@ -714,21 +717,18 @@ int main(int argc, char **argv)
if (pitData->Unpack(devicePit))
{
- pitData->Print();
+ Interface::PrintPit(pitData);
success = true;
}
else
{
- InterfaceManager::PrintError("Failed to unpack device's PIT file!\n");
+ Interface::PrintError("Failed to unpack device's PIT file!\n");
success = false;
}
delete pitData;
- if (noReboot)
- success = bridgeManager->EndSession() && success;
- else
- success = bridgeManager->EndSession() && bridgeManager->RebootDevice() && success;
+ success = bridgeManager->EndSession(reboot) && success;
break;
}