aboutsummaryrefslogtreecommitdiffstats
path: root/Heimdall/heimdall/source/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Heimdall/heimdall/source/main.cpp')
-rw-r--r--Heimdall/heimdall/source/main.cpp660
1 files changed, 0 insertions, 660 deletions
diff --git a/Heimdall/heimdall/source/main.cpp b/Heimdall/heimdall/source/main.cpp
deleted file mode 100644
index 037d097..0000000
--- a/Heimdall/heimdall/source/main.cpp
+++ /dev/null
@@ -1,660 +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 <algorithm>
-#include <map>
-#include <stdio.h>
-#include <string>
-
-// Heimdall
-#include "BridgeManager.h"
-#include "DeviceInfoPacket.h"
-#include "DeviceInfoResponse.h"
-#include "EndModemFileTransferPacket.h"
-#include "EndPhoneFileTransferPacket.h"
-#include "InterfaceManager.h"
-
-using namespace std;
-using namespace Heimdall;
-
-enum
-{
- kFilePit = 0,
- kFileFactoryFs,
- kFileCache,
- kFileData,
- kFilePrimaryBootloader,
- kFileSecondaryBootloader,
- kFileSecondaryBootloaderBackup,
- kFileParam,
- kFileKernel,
- kFileRecovery,
- kFileEfs,
- kFileModem,
- kFileCount
-};
-
-bool flashFile(BridgeManager *bridgeManager, FILE *file, int fileIndex)
-{
- switch (fileIndex)
- {
- case kFilePit:
-
- InterfaceManager::Print("Uploading PIT file\n");
- if (bridgeManager->SendPitFile(file))
- {
- InterfaceManager::Print("PIT file upload successful\n");
- return (true);
- }
- else
- {
- InterfaceManager::PrintError("PIT file upload failed!\n");
- return (false);
- }
-
- case kFileFactoryFs:
-
- InterfaceManager::Print("Uploading factory filesytem\n");
- if (bridgeManager->SendFile(file, EndPhoneFileTransferPacket::kDestinationPhone,
- EndPhoneFileTransferPacket::kFileFactoryFilesystem))
- {
- InterfaceManager::Print("Factory filesytem upload successful\n");
- return (true);
- }
- else
- {
- InterfaceManager::PrintError("Factory filesytem upload failed!\n");
- return (false);
- }
-
- case kFileCache:
-
- InterfaceManager::Print("Uploading cache\n");
- if (bridgeManager->SendFile(file, EndPhoneFileTransferPacket::kDestinationPhone,
- EndPhoneFileTransferPacket::kFileCache))
- {
- InterfaceManager::Print("Cache upload successful\n");
- return (true);
- }
- else
- {
- InterfaceManager::PrintError("Cache upload failed!\n");
- return (false);
- }
-
- case kFileData:
-
- InterfaceManager::Print("Uploading data database\n");
- if (bridgeManager->SendFile(file, EndPhoneFileTransferPacket::kDestinationPhone,
- EndPhoneFileTransferPacket::kFileDatabaseData))
- {
- InterfaceManager::Print("Data database upload successful\n");
- return (true);
- }
- else
- {
- InterfaceManager::PrintError("Data database upload failed!\n");
- return (false);
- }
-
- case kFilePrimaryBootloader:
-
- InterfaceManager::Print("Uploading primary bootloader\n");
- if (bridgeManager->SendFile(file, EndPhoneFileTransferPacket::kDestinationPhone,
- EndPhoneFileTransferPacket::kFilePrimaryBootloader))
- {
- InterfaceManager::Print("Primary bootloader upload successful\n");
- return (true);
- }
- else
- {
- InterfaceManager::PrintError("Primary bootloader upload failed!\n");
- return (false);
- }
-
- case kFileSecondaryBootloader:
-
- InterfaceManager::Print("Uploading secondary bootloader\n");
- if (bridgeManager->SendFile(file, EndPhoneFileTransferPacket::kDestinationPhone,
- EndPhoneFileTransferPacket::kFileSecondaryBootloader))
- {
- InterfaceManager::Print("Secondary bootloader upload successful\n");
- return (true);
- }
- else
- {
- InterfaceManager::PrintError("Secondary bootloader upload failed!\n");
- return (false);
- }
-
- case kFileSecondaryBootloaderBackup:
-
- InterfaceManager::Print("Uploading backup secondary bootloader\n");
- if (bridgeManager->SendFile(file, EndPhoneFileTransferPacket::kDestinationPhone,
- EndPhoneFileTransferPacket::kFileSecondaryBootloaderBackup))
- {
- InterfaceManager::Print("Backup secondary bootloader upload successful\n");
- return (true);
- }
- else
- {
- InterfaceManager::PrintError("Backup secondary bootloader upload failed!\n");
- return (false);
- }
-
- case kFileParam:
- InterfaceManager::Print("Uploading param.lfs\n");
- if (bridgeManager->SendFile(file, EndPhoneFileTransferPacket::kDestinationPhone,
- EndPhoneFileTransferPacket::kFileParamLfs))
- {
- InterfaceManager::Print("param.lfs upload successful\n");
- return (true);
- }
- else
- {
- InterfaceManager::PrintError("param.lfs upload failed!\n");
- return (false);
- }
-
- case kFileKernel:
-
- InterfaceManager::Print("Uploading kernel\n");
- if (bridgeManager->SendFile(file, EndPhoneFileTransferPacket::kDestinationPhone,
- EndPhoneFileTransferPacket::kFileKernel))
- {
- InterfaceManager::Print("Kernel upload successful\n");
- return (true);
- }
- else
- {
- InterfaceManager::PrintError("Kernel upload failed!\n");
- return (false);
- }
-
- case kFileModem:
-
- InterfaceManager::Print("Uploading modem\n");
-
- /*if (bridgeManager->SendFile(file, EndModemFileTransferPacket::kDestinationModem))*/ // <-- Odin method
- if (bridgeManager->SendFile(file, EndPhoneFileTransferPacket::kDestinationPhone, // <-- Kies method
- EndPhoneFileTransferPacket::kFileModem))
- {
- InterfaceManager::Print("Modem upload successful\n");
- return (true);
- }
- else
- {
- InterfaceManager::PrintError("Modem upload failed!\n");
- return (false);
- }
-
- case kFileRecovery:
-
- InterfaceManager::Print("Uploading recovery\n");
- if (bridgeManager->SendFile(file, EndPhoneFileTransferPacket::kDestinationPhone,
- EndPhoneFileTransferPacket::kFileRecovery))
- {
- InterfaceManager::Print("Recovery upload successful\n");
- return (true);
- }
- else
- {
- InterfaceManager::PrintError("Recovery upload failed!\n");
- return (false);
- }
-
- case kFileEfs:
-
- InterfaceManager::Print("Uploading EFS\n");
- if (bridgeManager->SendFile(file, EndPhoneFileTransferPacket::kDestinationPhone,
- EndPhoneFileTransferPacket::kFileEfs))
- {
- InterfaceManager::Print("EFS upload successful\n");
- return (true);
- }
- else
- {
- InterfaceManager::PrintError("EFS upload failed!\n");
- return (false);
- }
-
- default:
-
- InterfaceManager::PrintError("ERROR: Attempted to flash unknown file!\n");
- return (false);
- }
-}
-
-bool attemptFlash(BridgeManager *bridgeManager, FILE **fileArray, bool repartition)
-{
- bool success;
-
- // ---------- 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");
- return (false);
- }
-
- if (unknown != 0)
- {
- InterfaceManager::PrintError("Unexpected device info response!\nExpected: 0\nReceived:%i\n", unknown);
-
- if (!bridgeManager->EndSession())
- return (false);
- bridgeManager->RebootDevice();
-
- 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");
- 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, and 3 on the Galaxy Tab.
- if (unknown != 180 && unknown != 0 && unknown != 3)
- {
- InterfaceManager::PrintError("Unexpected device info response!\nExpected: 180, 0 or 3\nReceived:%i\n", unknown);
-
- if (!bridgeManager->EndSession())
- return (false);
- bridgeManager->RebootDevice();
-
- return (false);
- }
- // --------------------------------------------------------------
-
- int totalBytes = 0;
- for (int i = kFileFactoryFs; i < kFileCount; i++)
- {
- if (fileArray[i])
- {
- fseek(fileArray[i], 0, SEEK_END);
- totalBytes += ftell(fileArray[i]);
- rewind(fileArray[i]);
- }
- }
-
- if (repartition)
- {
- // When repartitioning we send the PIT file to the device.
- fseek(fileArray[kFilePit], 0, SEEK_END);
- totalBytes += ftell(fileArray[kFilePit]);
- rewind(fileArray[kFilePit]);
- }
-
- 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");
- 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);
- }
-
- if (unknown != 0)
- {
- InterfaceManager::PrintError("Unexpected device info response!\nExpected: 0\nReceived:%i\n", unknown);
-
- if (!bridgeManager->EndSession())
- return (false);
- bridgeManager->RebootDevice();
-
- return (false);
- }
-
- // -----------------------------------------------------
-
- if (fileArray[kFilePit])
- {
- if (repartition)
- {
- flashFile(bridgeManager, fileArray[kFilePit], kFilePit);
- }
- else // We're performing a PIT check
- {
- // Load the local pit file into memory.
- char *localPit = new char[4096];
- memset(localPit, 0, 4096);
-
- fseek(fileArray[kFilePit], 0, SEEK_END);
- long localPitFileSize = ftell(fileArray[kFilePit]);
- rewind(fileArray[kFilePit]);
-
- fread(localPit, 1, localPitFileSize, fileArray[kFilePit]);
-
- InterfaceManager::Print("Downloading device's PIT file...\n");
-
- unsigned char *devicePit;
- int devicePitFileSize = bridgeManager->ReceivePitFile(&devicePit);
-
- if (!devicePit)
- {
- InterfaceManager::PrintError("Failed to download PIT file!\n");
-
- if (!bridgeManager->EndSession())
- return (false);
- bridgeManager->RebootDevice();
-
- return (false);
- }
-
- InterfaceManager::Print("PIT file download sucessful\n\n");
-
- bool pitFilesMatch = !memcmp(localPit, devicePit, localPitFileSize);
-
- delete [] localPit;
- delete [] devicePit;
-
- if (!pitFilesMatch)
- {
- InterfaceManager::Print("Optional PIT check failed! To disable this check don't use the --pit parameter.");
-
- if (!bridgeManager->EndSession())
- return (false);
- bridgeManager->RebootDevice();
-
- return (false);
- }
- }
- }
-
- // Flash specified files
- for (int fileIndex = kFileFactoryFs; fileIndex < kFileCount; fileIndex++)
- {
- if (fileArray[fileIndex])
- {
- if (!flashFile(bridgeManager, fileArray[fileIndex], fileIndex))
- return (false);
- }
- }
-
- return (bridgeManager->EndSession() && bridgeManager->RebootDevice());
-}
-
-bool openFiles(const map<string, string>& argumentMap, FILE **fileArray)
-{
- for (int fileIndex = 0; fileIndex < kFileCount; fileIndex++)
- {
- // kFlashArgPit + kFile<Name> == kFlashArg<Name>
- map<string, string>::const_iterator it = argumentMap.find(InterfaceManager::flashArgumentNames[InterfaceManager::kFlashArgPit + fileIndex]);
- if (it == argumentMap.end())
- continue;
-
- fileArray[fileIndex] = fopen(it->second.c_str(), "rb");
- if (!fileArray[fileIndex])
- {
- InterfaceManager::PrintError("Failed to open file \"%s\"\n", it->second.c_str());
- return (false);
- }
- }
-
- return (true);
-}
-
-void closeFiles(FILE **fileArray)
-{
- for (int fileIndex = 0; fileIndex < kFileCount; fileIndex++)
- {
- if (fileArray[fileIndex] != nullptr)
- fclose(fileArray[fileIndex]);
- }
-}
-
-int main(int argc, char **argv)
-{
- map<string, string> argumentMap;
- int actionIndex;
-
- if (!InterfaceManager::GetArguments(argc, argv, argumentMap, &actionIndex))
- {
- Sleep(1000);
- return (0);
- }
-
- if (actionIndex == InterfaceManager::kActionHelp)
- {
- InterfaceManager::Print(InterfaceManager::usage);
- return (0);
- }
- else if (actionIndex == InterfaceManager::kActionFlash)
- {
- if (argumentMap.find(InterfaceManager::flashArgumentNames[InterfaceManager::kFlashArgRepartition]) != argumentMap.end()
- && (argumentMap.find(InterfaceManager::flashArgumentNames[InterfaceManager::kFlashArgPit]) == argumentMap.end()
- || argumentMap.find(InterfaceManager::flashArgumentNames[InterfaceManager::kFlashArgFactoryFs]) == argumentMap.end()
- || argumentMap.find(InterfaceManager::flashArgumentNames[InterfaceManager::kFlashArgCache]) == argumentMap.end()
- || argumentMap.find(InterfaceManager::flashArgumentNames[InterfaceManager::kFlashArgData]) == argumentMap.end()
- || argumentMap.find(InterfaceManager::flashArgumentNames[InterfaceManager::kFlashArgPrimaryBootloader]) == argumentMap.end()
- || argumentMap.find(InterfaceManager::flashArgumentNames[InterfaceManager::kFlashArgSecondaryBootloader]) == argumentMap.end()
- || argumentMap.find(InterfaceManager::flashArgumentNames[InterfaceManager::kFlashArgParam]) == argumentMap.end()
- || argumentMap.find(InterfaceManager::flashArgumentNames[InterfaceManager::kFlashArgKernel]) == argumentMap.end()))
- {
- InterfaceManager::Print("If you wish to repartition then factoryfs, cache, dbdata, primary and secondary\nbootloaders, param, kernel and a PIT file must all be specified.\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(InterfaceManager::dumpArgumentNames[InterfaceManager::kDumpArgChipType]) == argumentMap.end())
- {
- InterfaceManager::Print("You must specify a chip type.\n\n");
- InterfaceManager::Print(InterfaceManager::usage);
- return (0);
- }
-
- string chipType = argumentMap.find(InterfaceManager::dumpArgumentNames[InterfaceManager::kDumpArgChipType])->second;
- if (!(chipType == "RAM" || chipType == "ram" || chipType == "NAND" || chipType == "nand"))
- {
- InterfaceManager::Print("Unknown chip type: %s.\n\n", chipType.c_str());
- InterfaceManager::Print(InterfaceManager::usage);
- return (0);
- }
-
- if (argumentMap.find(InterfaceManager::dumpArgumentNames[InterfaceManager::kDumpArgChipId]) == argumentMap.end())
- {
- InterfaceManager::Print("You must specify a Chip ID.\n\n");
- InterfaceManager::Print(InterfaceManager::usage);
- 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");
- return (0);
- }
- }
-
- InterfaceManager::Print("\nHeimdall, Copyright (c) 2010, 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();
-
- int communicationDelay = BridgeManager::kCommunicationDelayDefault;
- if (argumentMap.find(InterfaceManager::commonArgumentNames[InterfaceManager::kCommonArgDelay]) != argumentMap.end())
- communicationDelay = atoi(argumentMap.find(InterfaceManager::commonArgumentNames[InterfaceManager::kCommonArgDelay])->second.c_str());
-
- BridgeManager *bridgeManager = new BridgeManager(verbose, communicationDelay);
-
- if (!bridgeManager->Initialise())
- {
- delete bridgeManager;
- return (-2);
- }
-
- bool success;
-
- switch (actionIndex)
- {
- case InterfaceManager::kActionFlash:
- {
- FILE **fileArray = new FILE *[kFileCount];
- for (int i = 0; i < kFileCount; i++)
- fileArray[i] = nullptr;
-
- // We open the files before doing anything else to ensure they exist.
- if (!openFiles(argumentMap, fileArray))
- {
- closeFiles(fileArray);
- delete [] fileArray;
-
- delete bridgeManager;
-
- return (0);
- }
-
- if (!bridgeManager->BeginSession())
- {
- closeFiles(fileArray);
- delete [] fileArray;
-
- delete bridgeManager;
-
- return (-1);
- }
-
- bool repartition = argumentMap.find(InterfaceManager::flashArgumentNames[InterfaceManager::kFlashArgRepartition]) != argumentMap.end();
- success = attemptFlash(bridgeManager, fileArray, repartition);
-
- closeFiles(fileArray);
- delete [] fileArray;
-
- break;
- }
-
- case InterfaceManager::kActionClosePcScreen:
- {
- if (!bridgeManager->BeginSession())
- {
- delete bridgeManager;
- return (-1);
- }
-
- InterfaceManager::Print("Attempting to close connect to pc screen...\n");
- success = bridgeManager->EndSession() && bridgeManager->RebootDevice();
-
- if (success)
- InterfaceManager::Print("Attempt complete\n");
-
- break;
- }
-
- case InterfaceManager::kActionDump:
- {
- const char *outputFilename = argumentMap.find(InterfaceManager::dumpArgumentNames[InterfaceManager::kDumpArgOutput])->second.c_str();
- FILE *dumpFile = fopen(outputFilename, "wb");
- if (!dumpFile)
- {
- InterfaceManager::PrintError("Failed to open file \"%s\"\n", outputFilename);
-
- delete bridgeManager;
- return (-1);
- }
-
- int chipType = 0;
- string chipTypeName = argumentMap.find(InterfaceManager::dumpArgumentNames[InterfaceManager::kDumpArgChipType])->second;
- if (chipTypeName == "NAND" || chipTypeName == "nand")
- chipType = 1;
-
- int chipId = atoi(argumentMap.find(InterfaceManager::dumpArgumentNames[InterfaceManager::kDumpArgChipId])->second.c_str());
-
- if (!bridgeManager->BeginSession())
- {
- fclose(dumpFile);
-
- delete bridgeManager;
-
- return (-1);
- }
-
- success = bridgeManager->ReceiveDump(chipType, chipId, dumpFile);
-
- fclose(dumpFile);
-
- if (success)
- success = bridgeManager->EndSession() && bridgeManager->RebootDevice();
-
- break;
- }
- }
-
- delete bridgeManager;
-
- return ((success) ? 0 : -1);
-} \ No newline at end of file