mirror of
https://git.sr.ht/~grimler/Heimdall
synced 2025-03-01 05:21:15 +00:00
- Swapped back to the "Odin method" of flashing modem files. (Galaxy Tab Fix) - Updated the README files slightly. - Removed unnecessary files /heimdall/source/.dirstamp
662 lines
19 KiB
C++
662 lines
19 KiB
C++
/* 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. WARNING: Doesn't work on Galaxy Tab!
|
|
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);
|
|
}
|