summaryrefslogtreecommitdiffstats
path: root/heimdall/source/Interface.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--heimdall/source/Interface.cpp484
1 files changed, 164 insertions, 320 deletions
diff --git a/heimdall/source/Interface.cpp b/heimdall/source/Interface.cpp
index 4d42ad0..67f1bee 100644
--- a/heimdall/source/Interface.cpp
+++ b/heimdall/source/Interface.cpp
@@ -24,342 +24,108 @@
#include <stdio.h>
// Heimdall
+#include "ClosePcScreenAction.h"
+#include "DetectAction.h"
+#include "DownloadPitAction.h"
+#include "DumpAction.h"
+#include "FlashAction.h"
+#include "HelpAction.h"
+#include "InfoAction.h"
#include "Heimdall.h"
#include "Interface.h"
+#include "PrintPitAction.h"
+#include "VersionAction.h"
using namespace std;
using namespace libpit;
using namespace Heimdall;
-bool Interface::stdoutErrors = false;
+map<string, Interface::ActionInfo> actionMap;
+bool stdoutErrors = false;
+
+const char *version = "v1.4 RC1";
+const char *actionUsage = "Usage: heimdall <action> <action arguments>\n";
-const char *Interface::version = "v1.3.2";
-
-const char *Interface::usage = "Usage: heimdall <action> <action arguments> <common arguments>\n\
-\n\
-Common Arguments:\n\
- [--verbose] [--no-reboot] [--stdout-errors] [--delay <ms>]\n\
-\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: download-pit\n\
-Arguments: --output <filename>\n\
-Description: Downloads the connected device's PIT file to the specified\n\
- output file.\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-2012, Benjamin Dobell, Glass Echidna\n\
-http://www.glassechidna.com.au\n\n\
+const char *releaseInfo = "Heimdall %s\n\n\
+Copyright (c) 2010-2012, 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";
-const char *Interface::extraInfo = "Heimdall utilises libusb-1.0 for all USB communication:\n\
+static const char *extraInfo = "Heimdall utilises libusb-1.0 for all USB communication:\n\
http://www.libusb.org/\n\
\n\
libusb-1.0 is licensed under the LGPL-2.1:\n\
http://www.gnu.org/licenses/licenses.html#LGPL\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"
-};
-
-// Download PIT arguments
-string Interface::downloadPitValueArguments[kDownloadPitValueArgCount] = {
- "-output"
-};
-
-string Interface::downloadPitValueShortArguments[kDownloadPitValueArgCount] = {
- "o"
-};
-
-// 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", "-stdout-errors"
-};
-
-string Interface::commonValuelessShortArguments[kCommonValuelessArgCount] = {
- "v", "nobt", "err"
-};
-
-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),
-
- // kActionDownloadPit
- Action("download-pit", downloadPitValueArguments, downloadPitValueShortArguments, kDownloadPitValueArgCount,
- nullptr, nullptr, kDownloadPitValuelessArgCount),
-
- // kActionInfo
- Action("info", nullptr, nullptr, kInfoValueArgCount,
- nullptr, nullptr, kInfoValuelessArgCount)
-};
-
-bool Interface::GetArguments(int argc, char **argv, map<string, string>& argumentMap, int *actionIndex)
+void populateActionMap(void)
{
- 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;
- }
- }
- }
+ actionMap["close-pc-screen"] = Interface::ActionInfo(&ClosePcScreenAction::Execute, ClosePcScreenAction::usage);
+ actionMap["detect"] = Interface::ActionInfo(&DetectAction::Execute, DetectAction::usage);
+ actionMap["download-pit"] = Interface::ActionInfo(&DownloadPitAction::Execute, DownloadPitAction::usage);
+ actionMap["dump"] = Interface::ActionInfo(&DumpAction::Execute, DumpAction::usage);
+ actionMap["flash"] = Interface::ActionInfo(&FlashAction::Execute, FlashAction::usage);
+ actionMap["help"] = Interface::ActionInfo(&HelpAction::Execute, HelpAction::usage);
+ actionMap["info"] = Interface::ActionInfo(&InfoAction::Execute, InfoAction::usage);
+ actionMap["print-pit"] = Interface::ActionInfo(&PrintPitAction::Execute, PrintPitAction::usage);
+ actionMap["version"] = Interface::ActionInfo(&VersionAction::Execute, VersionAction::usage);
+}
- if (valid)
- {
- // The argument is valueless
- argumentMap.insert(pair<string, string>(argumentName, ""));
- continue;
- }
+const map<string, Interface::ActionInfo>& Interface::GetActionMap(void)
+{
+ if (actionMap.size() == 0)
+ populateActionMap();
- // 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;
- }
- }
+ return actionMap;
+}
- if (argumentName == action.valueArguments[i] || argumentName == action.valueShortArguments[i])
- {
- argumentName = action.valueArguments[i];
- valid = true;
- break;
- }
- }
+void Interface::Print(const char *format, ...)
+{
+ va_list args;
+ va_start(args, format);
- 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;
- }
- }
- }
+ vfprintf(stdout, format, args);
+ fflush(stdout);
- if (!valid)
- {
- PrintError("\"%s\" is not a valid argument\n", argumentName.c_str());
- return (false);
- }
+ va_end(args);
+
+}
- argIndex++;
+void Interface::PrintWarning(const char *format, ...)
+{
+ va_list args;
+ va_start(args, format);
- if (argIndex >= argc)
- {
- PrintError("\"%s\" is missing a value\n", argumentName.c_str());
- return (false);
- }
+ fprintf(stderr, "WARNING: ");
+ vfprintf(stderr, format, args);
+ fflush(stderr);
- argumentMap.insert(pair<string, string>(argumentName, argv[argIndex]));
+ if (stdoutErrors)
+ {
+ fprintf(stdout, "WARNING: ");
+ vfprintf(stdout, format, args);
+ fflush(stdout);
}
- return (true);
+ va_end(args);
}
-void Interface::Print(const char *format, ...)
+void Interface::PrintWarningSameLine(const char *format, ...)
{
va_list args;
va_start(args, format);
- vfprintf(stdout, format, args);
- fflush(stdout);
+ vfprintf(stderr, format, args);
+ fflush(stderr);
+
+ if (stdoutErrors)
+ {
+ vfprintf(stdout, format, args);
+ fflush(stdout);
+ }
va_end(args);
-
}
void Interface::PrintError(const char *format, ...)
@@ -400,28 +166,33 @@ void Interface::PrintErrorSameLine(const char *format, ...)
void Interface::PrintVersion(void)
{
- Print("%s\n", version);
+ Interface::Print("%s\n", version);
}
void Interface::PrintUsage(void)
{
- Print(usage);
+ const map<string, ActionInfo>& actionMap = Interface::GetActionMap();
+
+ Interface::Print(actionUsage);
+
+ for (map<string, ActionInfo>::const_iterator it = actionMap.begin(); it != actionMap.end(); it++)
+ Interface::Print("\n%s", it->second.usage);
}
void Interface::PrintReleaseInfo(void)
{
- Print(releaseInfo, version);
+ Interface::Print(releaseInfo, version);
}
void Interface::PrintFullInfo(void)
{
- Print(releaseInfo, version);
- Print(extraInfo);
+ Interface::Print(releaseInfo, version);
+ Interface::Print(extraInfo);
}
void Interface::PrintDeviceDetectionFailed(void)
{
- Print("Failed to detect compatible download-mode device.\n");
+ Interface::PrintError("Failed to detect compatible download-mode device.\n");
}
void Interface::PrintPit(const PitData *pitData)
@@ -442,34 +213,107 @@ void Interface::PrintPit(const PitData *pitData)
const PitEntry *entry = pitData->GetEntry(i);
Interface::Print("\n\n--- Entry #%d ---\n", i);
- Interface::Print("Unused: %s\n", (entry->GetUnused()) ? "Yes" : "No");
+ Interface::Print("Binary Type: %d (", entry->GetBinaryType());
- const char *chipIdentifierText = "Unknown";
+ switch (entry->GetBinaryType())
+ {
+ case PitEntry::kBinaryTypeApplicationProcessor:
+ Interface::Print("AP");
+ break;
- Interface::Print("Chip Identifier: %d (%s)\n", entry->GetChipIdentifier());
+ case PitEntry::kBinaryTypeCommunicationProcessor:
+ Interface::Print("CP");
+ break;
- Interface::Print("Partition Identifier: %d\n", entry->GetPartitionIdentifier());
+ default:
+ Interface::Print("Unknown");
+ break;
+ }
- Interface::Print("Partition Flags: %d (", entry->GetPartitionFlags());
+ Interface::Print(")\n");
- if (entry->GetPartitionFlags() & PitEntry::kPartitionFlagWrite)
- Interface::Print("R/W");
+ Interface::Print("Device Type: %d (", entry->GetDeviceType());
+
+ switch (entry->GetDeviceType())
+ {
+ case PitEntry::kDeviceTypeOneNand:
+ Interface::Print("OneNAND");
+ break;
+
+ case PitEntry::kDeviceTypeFile:
+ Interface::Print("File/FAT");
+ break;
+
+ case PitEntry::kDeviceTypeMMC:
+ Interface::Print("MMC");
+ break;
+
+ case PitEntry::kDeviceTypeAll:
+ Interface::Print("All (?)");
+ break;
+
+ default:
+ Interface::Print("Unknown");
+ break;
+ }
+
+ Interface::Print(")\n");
+
+ Interface::Print("Identifier: %d\n", entry->GetIdentifier());
+
+ Interface::Print("Attributes: %d (", entry->GetAttributes());
+
+ if (entry->GetAttributes() & PitEntry::kAttributeSTL)
+ Interface::Print("STL ");
+
+ if (entry->GetAttributes() & PitEntry::kAttributeWrite)
+ Interface::Print("Read/Write");
else
- Interface::Print("R");
+ Interface::Print("Read-Only");
Interface::Print(")\n");
- Interface::Print("Unknown 1: %d\n", entry->GetUnknown1());
+ Interface::Print("Update Attributes: %d", entry->GetUpdateAttributes());
+
+ if (entry->GetUpdateAttributes())
+ {
+ Interface::Print(" (");
+
+ if (entry->GetUpdateAttributes() & PitEntry::kUpdateAttributeFota)
+ {
+ if (entry->GetUpdateAttributes() & PitEntry::kUpdateAttributeSecure)
+ Interface::Print("FOTA, Secure");
+ else
+ Interface::Print("FOTA");
+ }
+ else
+ {
+ if (entry->GetUpdateAttributes() & PitEntry::kUpdateAttributeSecure)
+ Interface::Print("Secure");
+ }
+
+ Interface::Print(")\n");
+ }
+ else
+ {
+ Interface::Print("\n");
+ }
- Interface::Print("Partition Block Size: %d\n", entry->GetPartitionBlockSize());
- Interface::Print("Partition Block Count: %d\n", entry->GetPartitionBlockCount());
+ Interface::Print("Partition Block Size: %d\n", entry->GetBlockSize());
+ Interface::Print("Partition Block Count: %d\n", entry->GetBlockCount());
- Interface::Print("Unknown 2: %d\n", entry->GetUnknown2());
- Interface::Print("Unknown 3: %d\n", entry->GetUnknown3());
+ Interface::Print("File Offset (Obsolete): %d\n", entry->GetFileOffset());
+ Interface::Print("File Size (Obsolete): %d\n", entry->GetFileSize());
Interface::Print("Partition Name: %s\n", entry->GetPartitionName());
- Interface::Print("Filename: %s\n", entry->GetFilename());
+ Interface::Print("Flash Filename: %s\n", entry->GetFlashFilename());
+ Interface::Print("FOTA Filename: %s\n", entry->GetFotaFilename());
}
Interface::Print("\n");
}
+
+void Interface::SetStdoutErrors(bool enabled)
+{
+ stdoutErrors = enabled;
+}