diff --git a/RKComm.cpp b/RKComm.cpp index 374cf4b..1538f65 100644 --- a/RKComm.cpp +++ b/RKComm.cpp @@ -196,6 +196,7 @@ void CRKUsbComm::InitializeCBW(PCBW pCBW, USB_OPERATION_CODE code) case READ_FLASH_INFO: case READ_CHIP_INFO: case READ_EFUSE: + case READ_CAPABILITY: pCBW->ucCBWFlags= DIRECTION_IN; pCBW->ucCBWCBLength = 0x06; break; @@ -427,6 +428,46 @@ int CRKUsbComm::RKU_ReadFlashInfo(BYTE* lpBuffer, UINT *puiRead) return ERR_SUCCESS; } +int CRKUsbComm::RKU_ReadCapability(BYTE* lpBuffer) +{ + if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) { + if (m_log) { + m_log->Record("Error:RKU_ReadCapability failed,device not support"); + } + return ERR_DEVICE_NOT_SUPPORT; + } + + CBW cbw; + CSW csw; + DWORD dwRead; + + InitializeCBW(&cbw, READ_CAPABILITY); + cbw.dwCBWTransferLength = 8; + + if(!RKU_Write((BYTE*)&cbw, sizeof(CBW))) + { + return ERR_DEVICE_WRITE_FAILED; + } + + dwRead = RKU_Read_EX((BYTE*)&csw, sizeof(CSW)); + + if(dwRead != 8) + { + return ERR_DEVICE_READ_FAILED; + } + memcpy(lpBuffer, (BYTE*)&csw, 8); + + if(!RKU_Read((BYTE*)&csw, sizeof(CSW))) + { + return ERR_DEVICE_READ_FAILED; + } + + if( !UFI_CHECK_SIGN(cbw, csw) ) + return ERR_CMD_NOTMATCH; + + return ERR_SUCCESS; +} + int CRKUsbComm::RKU_ReadLBA(DWORD dwPos, DWORD dwCount, BYTE* lpBuffer, BYTE bySubCode) { if ((m_deviceDesc.emUsbType != RKUSB_LOADER) && (m_deviceDesc.emUsbType != RKUSB_MASKROM)) { diff --git a/RKComm.h b/RKComm.h index a1a7eb0..9fd02c9 100644 --- a/RKComm.h +++ b/RKComm.h @@ -49,6 +49,7 @@ typedef enum { WRITE_NEW_EFUSE = 0x23, READ_NEW_EFUSE = 0x24, ERASE_LBA=0x25, + READ_CAPABILITY=0xAA, DEVICE_RESET = 0xFF } USB_OPERATION_CODE; @@ -117,6 +118,7 @@ public: virtual int RKU_EraseBlock(BYTE ucFlashCS, DWORD dwPos, DWORD dwCount, BYTE ucEraseType) = 0; virtual int RKU_ReadChipInfo(BYTE *lpBuffer) = 0; virtual int RKU_ReadFlashID(BYTE *lpBuffer) = 0; + virtual int RKU_ReadCapability(BYTE *lpBuffer)=0; virtual int RKU_ReadFlashInfo(BYTE *lpBuffer, UINT *puiRead = NULL) = 0; virtual int RKU_ReadLBA(DWORD dwPos, DWORD dwCount, BYTE *lpBuffer, BYTE bySubCode = RWMETHOD_IMAGE) = 0; virtual int RKU_ResetDevice(BYTE bySubCode = RST_NONE_SUBCODE) = 0; @@ -142,6 +144,7 @@ public: virtual int RKU_EraseBlock(BYTE ucFlashCS, DWORD dwPos, DWORD dwCount, BYTE ucEraseType); virtual int RKU_ReadChipInfo(BYTE *lpBuffer); virtual int RKU_ReadFlashID(BYTE *lpBuffer); + virtual int RKU_ReadCapability(BYTE *lpBuffer); virtual int RKU_ReadFlashInfo(BYTE *lpBuffer, UINT *puiRead = NULL); virtual int RKU_ReadLBA(DWORD dwPos, DWORD dwCount, BYTE *lpBuffer, BYTE bySubCode = RWMETHOD_IMAGE); virtual int RKU_ResetDevice(BYTE bySubCode = RST_NONE_SUBCODE); diff --git a/RKDevice.cpp b/RKDevice.cpp index ac5e830..a9bb9aa 100644 --- a/RKDevice.cpp +++ b/RKDevice.cpp @@ -175,6 +175,8 @@ CRKDevice::CRKDevice(STRUCT_RKDEVICE_DESC &device) m_usFlashInfoDataLen = 0; m_usFlashInfoDataOffset = 0; m_bEmmc = false; + m_bDirectLba = false; + m_bFirst4mAccess = false; } CRKDevice::~CRKDevice() { @@ -248,38 +250,44 @@ int CRKDevice::EraseEmmcByWriteLBA(DWORD dwSectorPos, DWORD dwCount) } bool CRKDevice::EraseEmmc() { - UINT uiCount, uiEraseCount, uiSectorOffset; - int iRet = ERR_SUCCESS, iLoopTimes = 0; - uiCount = m_flashInfo.uiFlashSize; - + UINT uiCount,uiEraseCount,uiSectorOffset,uiTotalCount; + UINT uiErase=1024*32; + int iRet=ERR_SUCCESS,iLoopTimes=0; + uiTotalCount = uiCount = m_flashInfo.uiFlashSize*2*1024; + uiSectorOffset = 0; DWORD dwLayerID; dwLayerID = m_locationID; ENUM_CALL_STEP emCallStep = CALL_FIRST; - uiEraseCount = 4; - while (uiEraseCount < uiCount) { - uiSectorOffset = uiEraseCount * 2048; - if (uiEraseCount>8) { - iRet = EraseEmmcByWriteLBA(uiSectorOffset, 32); - } else - iRet = EraseEmmcByWriteLBA(uiSectorOffset, 2048); + + while (uiCount) + { + if (uiCount >= uiErase) + { + uiEraseCount = uiErase; + } + else + uiEraseCount = uiCount; + iRet = m_pComm->RKU_EraseLBA(uiSectorOffset, uiEraseCount); + if (iRet != ERR_SUCCESS) { if (m_pLog) { - m_pLog->Record(" ERROR:EraseEmmc-->EraseEmmcByWriteLBA failed, RetCode(%d)", m_layerName, iRet); + m_pLog->Record("ERROR:EraseEmmc-->RKU_EraseLBA failed,RetCode(%d),offset=0x%x,count=0x%x",iRet, uiSectorOffset, uiEraseCount); } return false; } - uiEraseCount++; + uiCount -= uiEraseCount; + uiSectorOffset += uiEraseCount; iLoopTimes++; - if (iLoopTimes%8 == 0) { + if (iLoopTimes % 8 == 0) { if (m_callBackProc) { - m_callBackProc(dwLayerID, ERASEFLASH_PROGRESS, uiCount, uiEraseCount, emCallStep); + m_callBackProc(dwLayerID, ERASEFLASH_PROGRESS, uiTotalCount, uiSectorOffset, emCallStep); emCallStep = CALL_MIDDLE; } } } if (m_callBackProc) { emCallStep = CALL_LAST; - m_callBackProc(dwLayerID, ERASEFLASH_PROGRESS, uiCount, uiCount, emCallStep); + m_callBackProc(dwLayerID, ERASEFLASH_PROGRESS, uiTotalCount, uiTotalCount, emCallStep); } return true; } @@ -587,17 +595,11 @@ int CRKDevice::EraseAllBlocks() bCSCount++; } } + ReadCapability(); DWORD dwLayerID; dwLayerID = LocationID; ENUM_CALL_STEP emCallStep = CALL_FIRST; - if (m_bEmmc) { - iRet = EraseEmmcBlock(0, 0, IDBLOCK_TOP); - if (iRet != ERR_SUCCESS) { - if (m_pLog) { - m_pLog->Record(" ERROR:EraseAllBlocks-->EraseEmmcBlock failed,RetCode(%d)", m_layerName, iRet); - } - return -1; - } + if ((m_bEmmc)||(m_bDirectLba)) { if (!EraseEmmc()) { if (m_pLog) { m_pLog->Record(" ERROR:EraseAllBlocks-->EraseEmmc failed", m_layerName); @@ -640,4 +642,32 @@ int CRKDevice::EraseAllBlocks() } return 0; } +bool CRKDevice::ReadCapability() +{ + int ret; + BYTE data[8]; + ret = m_pComm->RKU_ReadCapability(data); + if (ret != ERR_SUCCESS) + { + if (m_pLog) + { + m_pLog->Record("ERROR:ReadCapability-->RKU_ReadCapability failed,err(%d)", ret); + } + return false; + } + if (data[0] & 0x1) + { + m_bDirectLba = true; + } + else + m_bDirectLba = false; + if (data[0] & 0x4) + { + m_bFirst4mAccess = true; + } + else + m_bFirst4mAccess = false; + return true; +} + diff --git a/RKDevice.h b/RKDevice.h index 515c109..20178d9 100644 --- a/RKDevice.h +++ b/RKDevice.h @@ -109,10 +109,13 @@ protected: CRKLog *m_pLog; ProgressPromptCB m_callBackProc; bool m_bEmmc; + bool m_bDirectLba; + bool m_bFirst4mAccess; int EraseEmmcBlock(UCHAR ucFlashCS, DWORD dwPos, DWORD dwCount); int EraseEmmcByWriteLBA(DWORD dwSectorPos, DWORD dwCount); bool EraseEmmc(); bool Boot_VendorRequest(DWORD requestCode, PBYTE pBuffer, DWORD dwDataSize); + bool ReadCapability(); private: USHORT m_vid; USHORT m_pid; diff --git a/configure.ac b/configure.ac index 16f6f9c..531ba85 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ dnl Copyright (C) 2017 Trevor Woerner -AC_INIT([Rockchip rkdeveloptool], 1.2, [Eddie Cai ], rkdeveloptool) +AC_INIT([Rockchip rkdeveloptool], 1.3, [Eddie Cai ], rkdeveloptool) AC_PREREQ([2.68]) AC_CONFIG_SRCDIR(main.cpp) AC_CONFIG_AUX_DIR(cfg) diff --git a/main.cpp b/main.cpp index fea5b7f..59c434f 100644 --- a/main.cpp +++ b/main.cpp @@ -44,19 +44,22 @@ void usage() printf("\r\n---------------------Tool Usage ---------------------\r\n"); printf("Help:\t\t\t-h or --help\r\n"); printf("Version:\t\t-v or --version\r\n"); + printf("ListDevice:\t\tld\r\n"); printf("DownloadBoot:\t\tdb \r\n"); printf("UpgradeLoader:\t\tul \r\n"); printf("ReadLBA:\t\trl \r\n"); printf("WriteLBA:\t\twl \r\n"); printf("WriteLBA:\t\twlx \r\n"); printf("WriteGPT:\t\tgpt \r\n"); - printf("PrintGPT:\t\tpgpt \r\n"); + printf("WriteParameter:\t\tprm \r\n"); + printf("PrintPartition:\t\tppt \r\n"); printf("EraseFlash:\t\tef \r\n"); printf("TestDevice:\t\ttd\r\n"); printf("ResetDevice:\t\trd [subcode]\r\n"); printf("ReadFlashID:\t\trid\r\n"); printf("ReadFlashInfo:\t\trfi\r\n"); printf("ReadChipInfo:\t\trci\r\n"); + printf("ReadCapability:\t\trcb\r\n"); printf("PackBootLoader:\t\tpack\r\n"); printf("UnpackBootLoader:\tunpack \r\n"); printf("TagSPL:\t\t\ttagspl \r\n"); @@ -608,6 +611,31 @@ bool get_lba_from_gpt(u8 *master, char *pszName, u64 *lba, u64 *lba_end) } return false; } +bool get_lba_from_param(u8 *param, char *pszName, u32 *part_offset, u32 *part_size) +{ + u32 i; + bool bFound = false, bRet; + PARAM_ITEM_VECTOR vecItem; + CONFIG_ITEM_VECTOR vecUuid; + + bRet = parse_parameter((char *)param, vecItem, vecUuid); + if (!bRet) + return false; + + for (i = 0; i < vecItem.size(); i++) { + if (strcasecmp(pszName, vecItem[i].szItemName)==0) { + bFound = true; + break; + } + } + if (bFound) { + *part_offset = vecItem[i].uiItemOffset; + *part_size = vecItem[i].uiItemSize; + return true; + } + return false; +} + void update_gpt_disksize(u8 *master, u8 *backup, u32 total_sector) { gpt_header *gptMasterHead = (gpt_header *)(master + SECTOR_SIZE); @@ -843,6 +871,100 @@ bool check_device_type(STRUCT_RKDEVICE_DESC &dev, UINT uiSupportType) return false; } } +bool MakeParamBuffer(char *pParamFile, char* &pParamData) +{ + FILE *file=NULL; + file = fopen(pParamFile, "rb"); + if( !file ) + { + if (g_pLogObject) + g_pLogObject->Record("MakeParamBuffer failed,err=%d,can't open file: %s\r\n", errno, pParamFile); + return false; + } + int iFileSize; + fseek(file,0,SEEK_END); + iFileSize = ftell(file); + fseek(file,0,SEEK_SET); + char *pParamBuf=NULL; + pParamBuf = new char[iFileSize + 12]; + if (!pParamBuf) + { + fclose(file); + return false; + } + memset(pParamBuf,0,iFileSize+12); + *(UINT *)(pParamBuf) = 0x4D524150; + + int iRead; + iRead = fread(pParamBuf+8,1,iFileSize,file); + if (iRead!=iFileSize) + { + if (g_pLogObject) + g_pLogObject->Record("MakeParamBuffer failed,err=%d,read=%d,total=%d\r\n", errno, iRead, iFileSize); + fclose(file); + delete []pParamBuf; + return false; + } + fclose(file); + + *(UINT *)(pParamBuf+4) = iFileSize; + *(UINT *)(pParamBuf+8+iFileSize) = CRC_32( (PBYTE)pParamBuf+8, iFileSize); + pParamData = pParamBuf; + return true; +} + +bool write_parameter(STRUCT_RKDEVICE_DESC &dev, char *szParameter) +{ + CRKComm *pComm = NULL; + char *pParamBuf = NULL, writeBuf[512*1024]; + int iRet, nParamSec, nParamSize; + bool bRet, bSuccess = false; + if (!check_device_type(dev, RKUSB_MASKROM|RKUSB_LOADER)) + return false; + + pComm = new CRKUsbComm(dev, g_pLogObject, bRet); + if (!bRet) { + ERROR_COLOR_ATTR; + printf("Creating Comm Object failed!"); + NORMAL_COLOR_ATTR; + printf("\r\n"); + return bSuccess; + } + if (!MakeParamBuffer(szParameter, pParamBuf)) { + ERROR_COLOR_ATTR; + printf("Generating parameter failed!"); + NORMAL_COLOR_ATTR; + printf("\r\n"); + return bSuccess; + } + printf("Writing parameter...\r\n"); + nParamSize = *(UINT *)(pParamBuf+4) + 12; + nParamSec = BYTE2SECTOR(nParamSize); + if (nParamSec > 1024) { + ERROR_COLOR_ATTR; + printf("parameter is too large!"); + NORMAL_COLOR_ATTR; + printf("\r\n"); + return bSuccess; + } + memset(writeBuf, 0, nParamSec*512); + memcpy(writeBuf, pParamBuf, nParamSize); + iRet = pComm->RKU_WriteLBA(0x2000, nParamSec, (BYTE *)writeBuf); + if (iRet != ERR_SUCCESS) { + ERROR_COLOR_ATTR; + printf("Writing parameter failed!"); + NORMAL_COLOR_ATTR; + printf("\r\n"); + return bSuccess; + } + + bSuccess = true; + CURSOR_MOVEUP_LINE(1); + CURSOR_DEL_LINE; + printf("Writing parameter succeeded.\r\n"); + return bSuccess; +} + bool write_gpt(STRUCT_RKDEVICE_DESC &dev, char *szParameter) { u8 flash_info[SECTOR_SIZE], master_gpt[34 * SECTOR_SIZE], backup_gpt[33 * SECTOR_SIZE]; @@ -1910,9 +2032,6 @@ bool print_gpt(STRUCT_RKDEVICE_DESC &dev) iRet = pComm->RKU_ReadLBA( 0, 34, master_gpt); if(ERR_SUCCESS == iRet) { if (gptHead->signature != le64_to_cpu(GPT_HEADER_SIGNATURE)) { - if (g_pLogObject) - g_pLogObject->Record("Error: invalid gpt signature"); - printf("Invalid GPT signature!\r\n"); goto Exit_PrintGpt; } @@ -1923,7 +2042,7 @@ bool print_gpt(STRUCT_RKDEVICE_DESC &dev) goto Exit_PrintGpt; } - printf("**********GPT Info**********\r\n"); + printf("**********Partition Info(GPT)**********\r\n"); printf("NO LBA Name \r\n"); for (i = 0; i < le32_to_cpu(gptHead->num_partition_entries); i++) { gptEntry = (gpt_entry *)(master_gpt + 2 * SECTOR_SIZE + i * GPT_ENTRY_SIZE); @@ -1943,6 +2062,58 @@ Exit_PrintGpt: delete pComm; return bSuccess; } +bool print_parameter(STRUCT_RKDEVICE_DESC &dev) +{ + if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) + return false; + u8 param_buf[512 * SECTOR_SIZE]; + bool bRet, bSuccess = false; + int iRet; + u32 i, nParamSize; + CRKComm *pComm = NULL; + PARAM_ITEM_VECTOR vecParamItem; + CONFIG_ITEM_VECTOR vecUuidItem; + pComm = new CRKUsbComm(dev, g_pLogObject, bRet); + if (!bRet) { + ERROR_COLOR_ATTR; + printf("Creating Comm Object failed!"); + NORMAL_COLOR_ATTR; + printf("\r\n"); + return bSuccess; + } + iRet = pComm->RKU_ReadLBA( 0x2000, 512, param_buf); + if(ERR_SUCCESS == iRet) { + if (*(u32 *)param_buf != 0x4D524150) { + goto Exit_PrintParam; + } + + } else { + if (g_pLogObject) + g_pLogObject->Record("Error: read parameter failed, err=%d", iRet); + printf("Read parameter failed!\r\n"); + goto Exit_PrintParam; + } + nParamSize = *(u32 *)(param_buf + 4); + memset(param_buf+8+nParamSize, 0, 512*SECTOR_SIZE - nParamSize - 8); + + bRet = parse_parameter((char *)(param_buf+8), vecParamItem, vecUuidItem); + if (!bRet) { + if (g_pLogObject) + g_pLogObject->Record("Error: parse parameter failed"); + printf("Parse parameter failed!\r\n"); + goto Exit_PrintParam; + } + printf("**********Partition Info(parameter)**********\r\n"); + printf("NO LBA Name \r\n"); + for (i = 0; i < vecParamItem.size(); i++) { + printf("%02d %08X %s\r\n", i, vecParamItem[i].uiItemOffset, vecParamItem[i].szItemName); + } + bSuccess = true; +Exit_PrintParam: + if (pComm) + delete pComm; + return bSuccess; +} bool erase_flash(STRUCT_RKDEVICE_DESC &dev) { @@ -2179,6 +2350,84 @@ bool read_chip_info(STRUCT_RKDEVICE_DESC &dev) } return bSuccess; } +bool read_capability(STRUCT_RKDEVICE_DESC &dev) +{ + CRKUsbComm *pComm = NULL; + bool bRet, bSuccess = false; + int iRet; + if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) + return bSuccess; + + pComm = new CRKUsbComm(dev, g_pLogObject, bRet); + if (bRet) { + + BYTE capability[8]; + iRet = pComm->RKU_ReadCapability(capability); + if (iRet != ERR_SUCCESS) + { + if (g_pLogObject) + g_pLogObject->Record("Error:read_capability failed,err=%d", iRet); + printf("Read capability Fail!\r\n"); + } else { + printf("Capability:%02X %02X %02X %02X %02X %02X %02X %02X \r\n", + capability[0], capability[1], capability[2], capability[3], + capability[4], capability[5], capability[6], capability[7]); + if (capability[0] & 1) + { + printf("Direct LBA:\tenabled\r\n"); + } + + if (capability[0] & 2) + { + printf("Vendor Storage:\tenabled\r\n"); + } + + if (capability[0] & 4) + { + printf("First 4m Access:\tenabled\r\n"); + } + bSuccess = true; + } + } else { + printf("Read capability quit, creating comm object failed!\r\n"); + } + if (pComm) { + delete pComm; + pComm = NULL; + } + return bSuccess; +} +bool read_param(STRUCT_RKDEVICE_DESC &dev, u8 *pParam) +{ + if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) + return false; + CRKUsbComm *pComm = NULL; + bool bRet, bSuccess = false; + int iRet; + pComm = new CRKUsbComm(dev, g_pLogObject, bRet); + if (bRet) { + iRet = pComm->RKU_ReadLBA( 0x2000, 512, pParam); + if(ERR_SUCCESS == iRet) { + if (*(u32 *)pParam != 0x4D524150) { + goto Exit_ReadParam; + } + } else { + if (g_pLogObject) + g_pLogObject->Record("Error: read parameter failed, err=%d", iRet); + printf("Read parameter failed!\r\n"); + goto Exit_ReadParam; + } + bSuccess = true; + } +Exit_ReadParam: + if (pComm) { + delete pComm; + pComm = NULL; + } + return bSuccess; +} + + bool read_gpt(STRUCT_RKDEVICE_DESC &dev, u8 *pGpt) { if (!check_device_type(dev, RKUSB_LOADER | RKUSB_MASKROM)) @@ -2192,12 +2441,8 @@ bool read_gpt(STRUCT_RKDEVICE_DESC &dev, u8 *pGpt) iRet = pComm->RKU_ReadLBA( 0, 34, pGpt); if(ERR_SUCCESS == iRet) { if (gptHead->signature != le64_to_cpu(GPT_HEADER_SIGNATURE)) { - if (g_pLogObject) - g_pLogObject->Record("Error: invalid gpt signature"); - printf("Invalid GPT signature!\r\n"); goto Exit_ReadGPT; } - } else { if (g_pLogObject) g_pLogObject->Record("Error: read gpt failed, err=%d", iRet); @@ -2653,6 +2898,31 @@ void tag_spl(char *tag, char *spl) printf("done\n"); return; } +void list_device(CRKScan *pScan) +{ + STRUCT_RKDEVICE_DESC desc; + string strDevType; + int i,cnt; + cnt = pScan->DEVICE_COUNTS; + if (cnt == 0) { + printf("not found any devices!\r\n"); + return; + } + for (i=0;iGetDevice(desc, i); + if (desc.emUsbType==RKUSB_MASKROM) + strDevType = "Maskrom"; + else if (desc.emUsbType==RKUSB_LOADER) + strDevType = "Loader"; + else + strDevType = "Unknown"; + printf("DevNo=%d\tVid=0x%x,Pid=0x%x,LocationID=%x\t%s\r\n",i+1,desc.usVid, + desc.usPid,desc.uiLocationID,strDevType.c_str()); + } + +} + bool handle_command(int argc, char* argv[], CRKScan *pScan) { @@ -2663,8 +2933,9 @@ bool handle_command(int argc, char* argv[], CRKScan *pScan) char *s; int i, ret; STRUCT_RKDEVICE_DESC dev; - u8 master_gpt[34 * SECTOR_SIZE]; + u8 master_gpt[34 * SECTOR_SIZE], param_buffer[512 * SECTOR_SIZE]; u64 lba, lba_end; + u32 part_size, part_offset; transform(strCmd.begin(), strCmd.end(), strCmd.begin(), (int(*)(int))toupper); s = (char*)strCmd.c_str(); @@ -2698,6 +2969,11 @@ bool handle_command(int argc, char* argv[], CRKScan *pScan) usage(); } cnt = pScan->Search(RKUSB_MASKROM | RKUSB_LOADER); + if(strcmp(strCmd.c_str(), "LD") == 0) { + list_device(pScan); + return true; + } + if (cnt < 1) { ERROR_COLOR_ATTR; printf("Did not find any rockusb device, please plug device in!"); @@ -2749,6 +3025,8 @@ bool handle_command(int argc, char* argv[], CRKScan *pScan) bSuccess = read_flash_info(dev); } else if (strcmp(strCmd.c_str(), "RCI") == 0) {//Read Chip Info bSuccess = read_chip_info(dev); + } else if (strcmp(strCmd.c_str(), "RCB") == 0) {//Read Capability + bSuccess = read_capability(dev); } else if(strcmp(strCmd.c_str(), "DB") == 0) { if (argc > 2) { string strLoader; @@ -2769,6 +3047,13 @@ bool handle_command(int argc, char* argv[], CRKScan *pScan) bSuccess = write_gpt(dev, (char *)strParameter.c_str()); } else printf("Parameter of [GPT] command is invalid, please check help!\r\n"); + } else if(strcmp(strCmd.c_str(), "PRM") == 0) { + if (argc > 2) { + string strParameter; + strParameter = argv[2]; + bSuccess = write_parameter(dev, (char *)strParameter.c_str()); + } else + printf("Parameter of [PRM] command is invalid, please check help!\r\n"); } else if(strcmp(strCmd.c_str(), "UL") == 0) { if (argc > 2) { string strLoader; @@ -2808,7 +3093,22 @@ bool handle_command(int argc, char* argv[], CRKScan *pScan) bSuccess = write_lba(dev, (u32)lba, argv[3]); } else printf("No found %s partition\r\n", argv[2]); - } + } else { + bRet = read_param(dev, param_buffer); + if (bRet) { + bRet = get_lba_from_param(param_buffer+8, argv[2], &part_offset, &part_size); + if (bRet) { + if (is_sparse_image(argv[3])) + bSuccess = write_sparse_lba(dev, part_offset, part_size, argv[3]); + else + bSuccess = write_lba(dev, part_offset, argv[3]); + } else + printf("No found %s partition\r\n", argv[2]); + } + else + printf("Not found any partition table!\r\n"); + } + } else printf("Parameter of [WLX] command is invalid, please check help!\r\n"); } else if (strcmp(strCmd.c_str(), "RL") == 0) {//Read LBA @@ -2829,11 +3129,16 @@ bool handle_command(int argc, char* argv[], CRKScan *pScan) } } } - } else if(strcmp(strCmd.c_str(), "PGPT") == 0) { + } else if(strcmp(strCmd.c_str(), "PPT") == 0) { if (argc == 2) { bSuccess = print_gpt(dev); + if (!bSuccess) { + bSuccess = print_parameter(dev); + if (!bSuccess) + printf("Not found any partition table!\r\n"); + } } else - printf("Parameter of [PGPT] command is invalid, please check help!\r\n"); + printf("Parameter of [PPT] command is invalid, please check help!\r\n"); } else { printf("command is invalid!\r\n"); usage();