diff options
Diffstat (limited to 'Heimdall/heimdall/source/main.cpp')
-rw-r--r-- | Heimdall/heimdall/source/main.cpp | 660 |
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 |