2013-10-08 15:07:03 +08:00
/* uefitool.cpp
2014-01-11 17:20:58 +08:00
Copyright ( c ) 2014 , Nikolaj Schlej . All rights reserved .
2013-10-08 15:07:03 +08:00
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution . The full text of the license may be found at
http : //opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN " AS IS " BASIS ,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND , EITHER EXPRESS OR IMPLIED .
*/
# include "uefitool.h"
# include "ui_uefitool.h"
UEFITool : : UEFITool ( QWidget * parent ) :
QMainWindow ( parent ) ,
ui ( new Ui : : UEFITool )
{
2013-12-05 04:27:12 +08:00
// Create UI
2013-10-08 15:07:03 +08:00
ui - > setupUi ( this ) ;
2013-12-05 04:27:12 +08:00
searchDialog = new SearchDialog ( this ) ;
2013-12-29 23:13:46 +08:00
ffsEngine = NULL ;
2013-12-05 04:27:12 +08:00
// Connect signals to slots
2013-10-15 23:19:15 +08:00
connect ( ui - > actionOpenImageFile , SIGNAL ( triggered ( ) ) , this , SLOT ( openImageFile ( ) ) ) ;
2013-12-29 23:13:46 +08:00
connect ( ui - > actionSaveImageFile , SIGNAL ( triggered ( ) ) , this , SLOT ( saveImageFile ( ) ) ) ;
connect ( ui - > actionSearch , SIGNAL ( triggered ( ) ) , this , SLOT ( search ( ) ) ) ;
2013-11-17 17:01:11 +08:00
connect ( ui - > actionExtract , SIGNAL ( triggered ( ) ) , this , SLOT ( extractAsIs ( ) ) ) ;
2013-11-07 21:46:28 +08:00
connect ( ui - > actionExtractBody , SIGNAL ( triggered ( ) ) , this , SLOT ( extractBody ( ) ) ) ;
connect ( ui - > actionInsertInto , SIGNAL ( triggered ( ) ) , this , SLOT ( insertInto ( ) ) ) ;
connect ( ui - > actionInsertBefore , SIGNAL ( triggered ( ) ) , this , SLOT ( insertBefore ( ) ) ) ;
connect ( ui - > actionInsertAfter , SIGNAL ( triggered ( ) ) , this , SLOT ( insertAfter ( ) ) ) ;
2013-12-12 19:28:39 +08:00
connect ( ui - > actionReplace , SIGNAL ( triggered ( ) ) , this , SLOT ( replaceAsIs ( ) ) ) ;
2013-12-29 23:13:46 +08:00
connect ( ui - > actionReplaceBody , SIGNAL ( triggered ( ) ) , this , SLOT ( replaceBody ( ) ) ) ;
2013-11-07 21:46:28 +08:00
connect ( ui - > actionRemove , SIGNAL ( triggered ( ) ) , this , SLOT ( remove ( ) ) ) ;
2013-11-18 23:23:59 +08:00
connect ( ui - > actionRebuild , SIGNAL ( triggered ( ) ) , this , SLOT ( rebuild ( ) ) ) ;
2013-12-05 04:27:12 +08:00
connect ( ui - > actionMessagesClear , SIGNAL ( triggered ( ) ) , this , SLOT ( clearMessages ( ) ) ) ;
2013-12-29 23:13:46 +08:00
connect ( ui - > actionAbout , SIGNAL ( triggered ( ) ) , this , SLOT ( about ( ) ) ) ;
2013-11-18 23:23:59 +08:00
connect ( ui - > actionAboutQt , SIGNAL ( triggered ( ) ) , this , SLOT ( aboutQt ( ) ) ) ;
connect ( ui - > actionQuit , SIGNAL ( triggered ( ) ) , this , SLOT ( exit ( ) ) ) ;
2013-12-05 04:27:12 +08:00
connect ( QCoreApplication : : instance ( ) , SIGNAL ( aboutToQuit ( ) ) , this , SLOT ( writeSettings ( ) ) ) ;
2013-10-08 15:07:03 +08:00
2013-12-05 04:27:12 +08:00
// Enable Drag-and-Drop actions
this - > setAcceptDrops ( true ) ;
2013-11-23 06:25:15 +08:00
2013-11-14 18:40:39 +08:00
// Initialize non-persistent data
2013-10-08 15:07:03 +08:00
init ( ) ;
2013-12-29 23:13:46 +08:00
// Read stored settings
readSettings ( ) ;
2013-11-23 06:25:15 +08:00
}
2013-10-08 15:07:03 +08:00
UEFITool : : ~ UEFITool ( )
{
delete ui ;
2013-10-15 23:19:15 +08:00
delete ffsEngine ;
2013-12-29 23:13:46 +08:00
delete searchDialog ;
2013-10-08 15:07:03 +08:00
}
void UEFITool : : init ( )
{
2013-12-29 23:13:46 +08:00
// Clear components
2013-11-17 17:01:11 +08:00
ui - > messageListWidget - > clear ( ) ;
2013-10-08 15:07:03 +08:00
ui - > infoEdit - > clear ( ) ;
2013-12-29 23:13:46 +08:00
2013-12-05 04:27:12 +08:00
// Disable menus
ui - > menuCapsuleActions - > setDisabled ( true ) ;
ui - > menuImageActions - > setDisabled ( true ) ;
ui - > menuRegionActions - > setDisabled ( true ) ;
ui - > menuPaddingActions - > setDisabled ( true ) ;
ui - > menuVolumeActions - > setDisabled ( true ) ;
ui - > menuFileActions - > setDisabled ( true ) ;
ui - > menuSectionActions - > setDisabled ( true ) ;
2013-10-15 23:19:15 +08:00
// Make new ffsEngine
2013-12-05 04:27:12 +08:00
if ( ffsEngine )
delete ffsEngine ;
2013-10-15 23:19:15 +08:00
ffsEngine = new FfsEngine ( this ) ;
2013-12-29 23:13:46 +08:00
ui - > structureTreeView - > setModel ( ffsEngine - > treeModel ( ) ) ;
2013-10-15 23:19:15 +08:00
// Connect
2013-10-08 15:07:03 +08:00
connect ( ui - > structureTreeView - > selectionModel ( ) , SIGNAL ( currentChanged ( const QModelIndex & , const QModelIndex & ) ) ,
2014-01-12 07:02:54 +08:00
this , SLOT ( populateUi ( const QModelIndex & ) ) ) ;
2013-11-17 17:01:11 +08:00
connect ( ui - > messageListWidget , SIGNAL ( itemDoubleClicked ( QListWidgetItem * ) ) , this , SLOT ( scrollTreeView ( QListWidgetItem * ) ) ) ;
2013-10-08 15:07:03 +08:00
}
2013-11-14 18:40:39 +08:00
void UEFITool : : populateUi ( const QModelIndex & current )
2013-10-08 15:07:03 +08:00
{
2013-11-17 17:01:11 +08:00
if ( ! current . isValid ( ) )
return ;
2013-12-29 23:13:46 +08:00
TreeModel * model = ffsEngine - > treeModel ( ) ;
UINT8 type = model - > type ( current ) ;
UINT8 subtype = model - > subtype ( current ) ;
2013-12-05 04:27:12 +08:00
// Set info text
2013-12-29 23:13:46 +08:00
ui - > infoEdit - > setPlainText ( model - > info ( current ) ) ;
2013-12-05 04:27:12 +08:00
// Enable menus
2013-12-29 23:13:46 +08:00
ui - > menuCapsuleActions - > setEnabled ( type = = Capsule ) ;
ui - > menuImageActions - > setEnabled ( type = = Image ) ;
ui - > menuRegionActions - > setEnabled ( type = = Region ) ;
ui - > menuPaddingActions - > setEnabled ( type = = Padding ) ;
ui - > menuVolumeActions - > setEnabled ( type = = Volume ) ;
ui - > menuFileActions - > setEnabled ( type = = File ) ;
ui - > menuSectionActions - > setEnabled ( type = = Section ) ;
2013-12-05 04:27:12 +08:00
// Enable actions
2013-12-29 23:13:46 +08:00
ui - > actionExtract - > setDisabled ( model - > hasEmptyHeader ( current ) & & model - > hasEmptyBody ( current ) & & model - > hasEmptyTail ( current ) ) ;
ui - > actionRebuild - > setDisabled ( model - > hasEmptyHeader ( current ) & & model - > hasEmptyBody ( current ) & & model - > hasEmptyTail ( current ) ) ;
ui - > actionExtractBody - > setDisabled ( model - > hasEmptyHeader ( current ) ) ;
ui - > actionRemove - > setEnabled ( type = = Volume | | type = = File | | type = = Section ) ;
ui - > actionInsertInto - > setEnabled ( type = = Volume | | ( type = = File & & subtype ! = EFI_FV_FILETYPE_ALL & & subtype ! = EFI_FV_FILETYPE_RAW & & subtype ! = EFI_FV_FILETYPE_PAD ) ) ;
ui - > actionInsertBefore - > setEnabled ( type = = File | | type = = Section ) ;
ui - > actionInsertAfter - > setEnabled ( type = = File | | type = = Section ) ;
ui - > actionReplace - > setEnabled ( type = = File | | type = = Section ) ;
ui - > actionReplaceBody - > setEnabled ( type = = File | | type = = Section ) ;
2013-11-18 23:23:59 +08:00
}
2013-12-05 04:27:12 +08:00
void UEFITool : : search ( )
{
2014-01-12 07:02:54 +08:00
// Set focus to edit box
searchDialog - > ui - > searchEdit - > setFocus ( ) ;
2013-12-29 23:13:46 +08:00
if ( searchDialog - > exec ( ) ! = QDialog : : Accepted )
return ;
2013-12-05 04:27:12 +08:00
2013-12-29 23:13:46 +08:00
int index = searchDialog - > ui - > dataTypeComboBox - > currentIndex ( ) ;
if ( index = = 0 ) { // Hex pattern
2013-12-05 18:53:24 +08:00
QByteArray pattern = QByteArray : : fromHex ( searchDialog - > ui - > searchEdit - > text ( ) . toLatin1 ( ) ) ;
2013-12-29 23:13:46 +08:00
if ( pattern . isEmpty ( ) )
return ;
UINT8 mode ;
if ( searchDialog - > ui - > headerOnlyRadioButton - > isChecked ( ) )
mode = SEARCH_MODE_HEADER ;
else if ( searchDialog - > ui - > bodyOnlyRadioButton - > isChecked ( ) )
mode = SEARCH_MODE_BODY ;
else
mode = SEARCH_MODE_ALL ;
ffsEngine - > findHexPattern ( pattern , mode ) ;
showMessages ( ) ;
}
else if ( index = = 1 ) { // Text string
QString pattern = searchDialog - > ui - > searchEdit - > text ( ) ;
if ( pattern . isEmpty ( ) )
return ;
ffsEngine - > findTextPattern ( pattern , searchDialog - > ui - > unicodeCheckBox - > isChecked ( ) ,
2014-01-12 07:02:54 +08:00
( Qt : : CaseSensitivity ) searchDialog - > ui - > caseSensitiveCheckBox - > isChecked ( ) ) ;
2013-12-29 23:13:46 +08:00
showMessages ( ) ;
}
2013-12-05 04:27:12 +08:00
}
2013-11-18 23:23:59 +08:00
void UEFITool : : rebuild ( )
{
QModelIndex index = ui - > structureTreeView - > selectionModel ( ) - > currentIndex ( ) ;
if ( ! index . isValid ( ) )
return ;
UINT8 result = ffsEngine - > rebuild ( index ) ;
2013-12-29 23:13:46 +08:00
2013-11-18 23:23:59 +08:00
if ( result = = ERR_SUCCESS )
ui - > actionSaveImageFile - > setEnabled ( true ) ;
2013-11-07 21:46:28 +08:00
}
void UEFITool : : remove ( )
{
2013-11-17 17:01:11 +08:00
QModelIndex index = ui - > structureTreeView - > selectionModel ( ) - > currentIndex ( ) ;
if ( ! index . isValid ( ) )
return ;
UINT8 result = ffsEngine - > remove ( index ) ;
if ( result = = ERR_SUCCESS )
2013-11-07 21:46:28 +08:00
ui - > actionSaveImageFile - > setEnabled ( true ) ;
}
2013-11-14 18:40:39 +08:00
void UEFITool : : insert ( const UINT8 mode )
2013-11-07 21:46:28 +08:00
{
2013-11-17 17:01:11 +08:00
QModelIndex index = ui - > structureTreeView - > selectionModel ( ) - > currentIndex ( ) ;
if ( ! index . isValid ( ) )
return ;
2013-12-29 23:13:46 +08:00
TreeModel * model = ffsEngine - > treeModel ( ) ;
2013-11-14 18:40:39 +08:00
UINT8 type ;
2013-11-17 17:01:11 +08:00
2013-12-12 19:28:39 +08:00
if ( mode = = CREATE_MODE_BEFORE | | mode = = CREATE_MODE_AFTER )
2013-12-29 23:13:46 +08:00
type = model - > type ( index . parent ( ) ) ;
2013-11-14 18:40:39 +08:00
else
2013-12-29 23:13:46 +08:00
type = model - > type ( index ) ;
2013-11-14 18:40:39 +08:00
2013-11-17 17:01:11 +08:00
QString path ;
2013-11-14 18:40:39 +08:00
switch ( type ) {
2013-12-29 23:13:46 +08:00
case Volume :
2013-11-23 06:25:15 +08:00
path = QFileDialog : : getOpenFileName ( this , tr ( " Select FFS file to insert " ) , " . " , " FFS files (*.ffs *.bin);;All files (*.*) " ) ;
2014-01-12 07:02:54 +08:00
break ;
2013-12-29 23:13:46 +08:00
case File :
case Section :
2013-11-23 06:25:15 +08:00
path = QFileDialog : : getOpenFileName ( this , tr ( " Select section file to insert " ) , " . " , " Section files (*.sct *.bin);;All files (*.*) " ) ;
2014-01-12 07:02:54 +08:00
break ;
2013-11-14 18:40:39 +08:00
default :
2013-11-07 21:46:28 +08:00
return ;
}
QFileInfo fileInfo = QFileInfo ( path ) ;
2013-11-23 06:25:15 +08:00
if ( ! fileInfo . exists ( ) ) {
2013-11-14 18:40:39 +08:00
ui - > statusBar - > showMessage ( tr ( " Please select existing file " ) ) ;
2013-11-07 21:46:28 +08:00
return ;
}
QFile inputFile ;
inputFile . setFileName ( path ) ;
2013-11-23 06:25:15 +08:00
if ( ! inputFile . open ( QFile : : ReadOnly ) ) {
2013-11-07 21:46:28 +08:00
ui - > statusBar - > showMessage ( tr ( " Can't open file for reading " ) ) ;
return ;
}
QByteArray buffer = inputFile . readAll ( ) ;
inputFile . close ( ) ;
2013-12-12 19:28:39 +08:00
UINT8 result = ffsEngine - > insert ( index , buffer , mode ) ;
2013-11-07 21:46:28 +08:00
if ( result )
2013-11-14 18:40:39 +08:00
ui - > statusBar - > showMessage ( tr ( " File can't be inserted (%1) " ) . arg ( result ) ) ;
2013-11-07 21:46:28 +08:00
else
ui - > actionSaveImageFile - > setEnabled ( true ) ;
2013-10-08 15:07:03 +08:00
}
2013-11-14 18:40:39 +08:00
void UEFITool : : insertInto ( )
2013-11-07 21:46:28 +08:00
{
2013-12-12 19:28:39 +08:00
insert ( CREATE_MODE_PREPEND ) ;
2013-11-14 18:40:39 +08:00
}
2013-11-07 21:46:28 +08:00
2013-11-14 18:40:39 +08:00
void UEFITool : : insertBefore ( )
{
2013-12-12 19:28:39 +08:00
insert ( CREATE_MODE_BEFORE ) ;
2013-11-14 18:40:39 +08:00
}
2013-11-07 21:46:28 +08:00
2013-11-14 18:40:39 +08:00
void UEFITool : : insertAfter ( )
{
2013-12-12 19:28:39 +08:00
insert ( CREATE_MODE_AFTER ) ;
2013-11-07 21:46:28 +08:00
}
2013-12-12 19:28:39 +08:00
void UEFITool : : replaceAsIs ( )
2013-11-07 21:46:28 +08:00
{
2013-12-12 19:28:39 +08:00
replace ( REPLACE_MODE_AS_IS ) ;
2013-11-07 21:46:28 +08:00
}
2013-12-12 19:28:39 +08:00
void UEFITool : : replaceBody ( )
2013-11-18 23:23:59 +08:00
{
2013-12-12 19:28:39 +08:00
replace ( REPLACE_MODE_BODY ) ;
2013-11-18 23:23:59 +08:00
}
2013-12-12 19:28:39 +08:00
void UEFITool : : replace ( const UINT8 mode )
2013-11-18 23:23:59 +08:00
{
2013-12-29 23:13:46 +08:00
QModelIndex index = ui - > structureTreeView - > selectionModel ( ) - > currentIndex ( ) ;
2013-11-18 23:23:59 +08:00
if ( ! index . isValid ( ) )
return ;
2013-12-12 19:28:39 +08:00
2013-12-29 23:13:46 +08:00
TreeModel * model = ffsEngine - > treeModel ( ) ;
QString path ;
if ( model - > type ( index ) = = File ) {
if ( mode = = REPLACE_MODE_AS_IS ) {
path = QFileDialog : : getOpenFileName ( this , tr ( " Select FFS file to replace selected object " ) , " . " , " FFS files (*.ffs *.bin);;All files (*.*) " ) ;
}
else if ( mode = = REPLACE_MODE_BODY ) {
if ( model - > subtype ( index ) = = EFI_FV_FILETYPE_ALL | | model - > subtype ( index ) = = EFI_FV_FILETYPE_RAW )
path = QFileDialog : : getOpenFileName ( this , tr ( " Select raw file to replace body " ) , " . " , " Raw files (*.raw *.bin);;All files (*.*) " ) ;
else if ( model - > subtype ( index ) = = EFI_FV_FILETYPE_PAD ) // Pad file body can't be replaced
return ;
else
path = QFileDialog : : getOpenFileName ( this , tr ( " Select FFS file body to replace body " ) , " . " , " FFS file body files (*.fbd *.bin);;All files (*.*) " ) ;
}
else
return ;
}
else if ( model - > type ( index ) = = Section ) {
if ( mode = = REPLACE_MODE_AS_IS ) {
path = QFileDialog : : getOpenFileName ( this , tr ( " Select section file to replace selected object " ) , " . " , " Section files (*.sec *.bin);;All files (*.*) " ) ;
}
else if ( mode = = REPLACE_MODE_BODY ) {
if ( model - > subtype ( index ) = = EFI_SECTION_COMPRESSION | | model - > subtype ( index ) = = EFI_SECTION_GUID_DEFINED | | model - > subtype ( index ) = = EFI_SECTION_DISPOSABLE )
path = QFileDialog : : getOpenFileName ( this , tr ( " Select FFS file body file to replace body " ) , " . " , " FFS file body files (*.fbd *.bin);;All files (*.*) " ) ;
else if ( model - > subtype ( index ) = = EFI_SECTION_FIRMWARE_VOLUME_IMAGE )
path = QFileDialog : : getOpenFileName ( this , tr ( " Select volume file to replace body " ) , " . " , " Volume files (*.vol *.bin);;All files (*.*) " ) ;
else if ( model - > subtype ( index ) = = EFI_SECTION_RAW )
path = QFileDialog : : getOpenFileName ( this , tr ( " Select raw file to replace body " ) , " . " , " Raw files (*.raw *.bin);;All files (*.*) " ) ;
else
path = QFileDialog : : getOpenFileName ( this , tr ( " Select file to replace body " ) , " . " , " Binary files (*.bin);;All files (*.*) " ) ;
}
else
return ;
}
else
return ;
QFileInfo fileInfo = QFileInfo ( path ) ;
2013-12-12 19:28:39 +08:00
if ( ! fileInfo . exists ( ) ) {
ui - > statusBar - > showMessage ( tr ( " Please select existing file " ) ) ;
return ;
}
QFile inputFile ;
inputFile . setFileName ( path ) ;
if ( ! inputFile . open ( QFile : : ReadOnly ) ) {
ui - > statusBar - > showMessage ( tr ( " Can't open file for reading " ) ) ;
return ;
}
QByteArray buffer = inputFile . readAll ( ) ;
inputFile . close ( ) ;
UINT8 result = ffsEngine - > replace ( index , buffer , mode ) ;
if ( result )
ui - > statusBar - > showMessage ( tr ( " File can't be replaced (%1) " ) . arg ( result ) ) ;
else
2013-11-18 23:23:59 +08:00
ui - > actionSaveImageFile - > setEnabled ( true ) ;
}
2013-12-12 19:28:39 +08:00
void UEFITool : : extractAsIs ( )
2013-11-18 23:23:59 +08:00
{
2013-12-12 19:28:39 +08:00
extract ( EXTRACT_MODE_AS_IS ) ;
}
void UEFITool : : extractBody ( )
{
extract ( EXTRACT_MODE_BODY ) ;
2013-11-18 23:23:59 +08:00
}
2013-12-12 19:28:39 +08:00
void UEFITool : : extract ( const UINT8 mode )
2013-11-19 00:11:08 +08:00
{
QModelIndex index = ui - > structureTreeView - > selectionModel ( ) - > currentIndex ( ) ;
if ( ! index . isValid ( ) )
return ;
2013-12-29 23:13:46 +08:00
TreeModel * model = ffsEngine - > treeModel ( ) ;
UINT8 type = model - > type ( index ) ;
2013-12-12 19:28:39 +08:00
QString path ;
if ( mode = = EXTRACT_MODE_AS_IS ) {
switch ( type ) {
2013-12-29 23:13:46 +08:00
case Capsule :
2013-12-12 19:28:39 +08:00
path = QFileDialog : : getSaveFileName ( this , tr ( " Save capsule to file " ) , " . " , " Capsule files (*.cap *.bin);;All files (*.*) " ) ;
break ;
2013-12-29 23:13:46 +08:00
case Image :
2013-12-12 19:28:39 +08:00
path = QFileDialog : : getSaveFileName ( this , tr ( " Save image to file " ) , " . " , " Image files (*.rom *.bin);;All files (*.*) " ) ;
break ;
2013-12-29 23:13:46 +08:00
case Region :
2013-12-12 19:28:39 +08:00
path = QFileDialog : : getSaveFileName ( this , tr ( " Save region to file " ) , " . " , " Region files (*.rgn *.bin);;All files (*.*) " ) ;
break ;
2013-12-29 23:13:46 +08:00
case Padding :
2013-12-12 19:28:39 +08:00
path = QFileDialog : : getSaveFileName ( this , tr ( " Save padding to file " ) , " . " , " Padding files (*.pad *.bin);;All files (*.*) " ) ;
break ;
2013-12-29 23:13:46 +08:00
case Volume :
2013-12-12 19:28:39 +08:00
path = QFileDialog : : getSaveFileName ( this , tr ( " Save volume to file " ) , " . " , " Volume files (*.vol *.bin);;All files (*.*) " ) ;
break ;
2013-12-29 23:13:46 +08:00
case File :
2013-12-12 19:28:39 +08:00
path = QFileDialog : : getSaveFileName ( this , tr ( " Save FFS file to file " ) , " . " , " FFS files (*.ffs *.bin);;All files (*.*) " ) ;
break ;
2013-12-29 23:13:46 +08:00
case Section :
2013-12-12 19:28:39 +08:00
path = QFileDialog : : getSaveFileName ( this , tr ( " Save section file to file " ) , " . " , " Section files (*.sct *.bin);;All files (*.*) " ) ;
2014-01-12 07:02:54 +08:00
break ;
2013-12-12 19:28:39 +08:00
default :
2013-12-29 23:13:46 +08:00
path = QFileDialog : : getSaveFileName ( this , tr ( " Save object to file " ) , " . " , " Binary files (*.bin);;All files (*.*) " ) ;
2013-12-12 19:28:39 +08:00
}
}
2013-12-29 23:13:46 +08:00
else if ( mode = = EXTRACT_MODE_BODY ) {
2013-12-12 19:28:39 +08:00
switch ( type ) {
2013-12-29 23:13:46 +08:00
case Capsule :
2013-12-12 19:28:39 +08:00
path = QFileDialog : : getSaveFileName ( this , tr ( " Save capsule body to image file " ) , " . " , " Image files (*.rom *.bin);;All files (*.*) " ) ;
break ;
2013-12-29 23:13:46 +08:00
case File : {
2014-01-12 07:02:54 +08:00
if ( model - > subtype ( index ) = = EFI_FV_FILETYPE_ALL | | model - > subtype ( index ) = = EFI_FV_FILETYPE_RAW )
path = QFileDialog : : getSaveFileName ( this , tr ( " Save FFS file body to raw file " ) , " . " , " Raw files (*.raw *.bin);;All files (*.*) " ) ;
else
path = QFileDialog : : getSaveFileName ( this , tr ( " Save FFS file body to file " ) , " . " , " FFS file body files (*.fbd *.bin);;All files (*.*) " ) ;
}
2013-12-12 19:28:39 +08:00
break ;
2013-12-29 23:13:46 +08:00
case Section : {
if ( model - > subtype ( index ) = = EFI_SECTION_COMPRESSION | | model - > subtype ( index ) = = EFI_SECTION_GUID_DEFINED | | model - > subtype ( index ) = = EFI_SECTION_DISPOSABLE )
path = QFileDialog : : getSaveFileName ( this , tr ( " Save encapsulated section body to FFS body file " ) , " . " , " FFS file body files (*.fbd *.bin);;All files (*.*) " ) ;
else if ( model - > subtype ( index ) = = EFI_SECTION_FIRMWARE_VOLUME_IMAGE )
path = QFileDialog : : getSaveFileName ( this , tr ( " Save section body to volume file " ) , " . " , " Volume files (*.vol *.bin);;All files (*.*) " ) ;
else if ( model - > subtype ( index ) = = EFI_SECTION_RAW )
path = QFileDialog : : getSaveFileName ( this , tr ( " Save section body to raw file " ) , " . " , " Raw files (*.raw *.bin);;All files (*.*) " ) ;
else
path = QFileDialog : : getSaveFileName ( this , tr ( " Save section body to file " ) , " . " , " Binary files (*.bin);;All files (*.*) " ) ;
2014-01-12 07:02:54 +08:00
}
break ;
2013-12-12 19:28:39 +08:00
default :
2013-12-29 23:13:46 +08:00
path = QFileDialog : : getSaveFileName ( this , tr ( " Save object to file " ) , " . " , " Binary files (*.bin);;All files (*.*) " ) ;
2013-12-12 19:28:39 +08:00
}
}
else
path = QFileDialog : : getSaveFileName ( this , tr ( " Save object to file " ) , " . " , " Binary files (*.bin);;All files (*.*) " ) ;
2013-12-29 23:13:46 +08:00
2013-12-12 19:28:39 +08:00
QFile outputFile ;
outputFile . setFileName ( path ) ;
if ( ! outputFile . open ( QFile : : WriteOnly ) ) {
ui - > statusBar - > showMessage ( tr ( " Can't open file for rewriting " ) ) ;
return ;
}
QByteArray extracted ;
UINT8 result = ffsEngine - > extract ( index , extracted , mode ) ;
2013-12-29 23:13:46 +08:00
if ( result )
2013-12-12 19:28:39 +08:00
ui - > statusBar - > showMessage ( tr ( " File can't be extracted (%1) " ) . arg ( result ) ) ;
else {
outputFile . resize ( 0 ) ;
outputFile . write ( extracted ) ;
outputFile . close ( ) ;
}
2013-11-19 00:11:08 +08:00
}
2013-11-18 23:23:59 +08:00
void UEFITool : : about ( )
{
2013-12-05 04:27:12 +08:00
QMessageBox : : about ( this , tr ( " About UEFITool " ) , tr (
2014-01-15 04:09:18 +08:00
" Copyright (c) 2013-2014, Nikolaj Schlej aka <b>CodeRush</b>.<br><br> "
2014-01-12 07:02:54 +08:00
" The program is dedicated to <b>RevoGirl</b>. Rest in peace, young genius.<br><br> "
" The program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License.<br> "
" The full text of the license may be found at <a href=http://opensource.org/licenses/bsd-license.php>OpenSource.org</a>.<br><br> "
" <b>THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN \" AS IS \" BASIS, "
" WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, "
" EITHER EXPRESS OR IMPLIED.</b> " ) ) ;
2013-11-18 23:23:59 +08:00
}
void UEFITool : : aboutQt ( )
{
QMessageBox : : aboutQt ( this , tr ( " About Qt " ) ) ;
}
2013-11-20 10:08:39 +08:00
void UEFITool : : exit ( )
{
2013-12-29 23:13:46 +08:00
QCoreApplication : : exit ( 0 ) ;
2013-11-20 10:08:39 +08:00
}
2013-11-07 21:46:28 +08:00
void UEFITool : : saveImageFile ( )
{
2013-12-12 19:28:39 +08:00
QString path = QFileDialog : : getSaveFileName ( this , tr ( " Save BIOS image file " ) , " . " , " BIOS image files (*.rom *.bin *.cap *.bio *.fd *.wph *.efi);;All files (*.*) " ) ;
2013-11-07 21:46:28 +08:00
QFile outputFile ;
outputFile . setFileName ( path ) ;
2013-11-23 06:25:15 +08:00
if ( ! outputFile . open ( QFile : : WriteOnly ) ) {
2013-11-07 21:46:28 +08:00
ui - > statusBar - > showMessage ( tr ( " Can't open file for writing " ) ) ;
return ;
2013-12-29 23:13:46 +08:00
}
2013-11-07 21:46:28 +08:00
QByteArray reconstructed ;
2014-01-15 04:09:18 +08:00
UINT8 result = ffsEngine - > reconstructImageFile ( reconstructed ) ;
2013-12-05 04:27:12 +08:00
showMessages ( ) ;
2013-11-23 06:25:15 +08:00
if ( result ) {
2013-11-07 21:46:28 +08:00
ui - > statusBar - > showMessage ( tr ( " Reconstruction failed (%1) " ) . arg ( result ) ) ;
return ;
}
2013-11-14 18:40:39 +08:00
outputFile . resize ( 0 ) ;
2013-11-07 21:46:28 +08:00
outputFile . write ( reconstructed ) ;
outputFile . close ( ) ;
ui - > statusBar - > showMessage ( tr ( " Reconstructed image written " ) ) ;
}
2013-10-08 15:07:03 +08:00
void UEFITool : : openImageFile ( )
{
2013-11-23 06:25:15 +08:00
QString path = QFileDialog : : getOpenFileName ( this , tr ( " Open BIOS image file " ) , " . " , " BIOS image files (*.rom *.bin *.cap *.bio *.fd *.wph *.efi);;All files (*.*) " ) ;
2013-10-08 15:07:03 +08:00
openImageFile ( path ) ;
}
void UEFITool : : openImageFile ( QString path )
{
QFileInfo fileInfo = QFileInfo ( path ) ;
2013-11-23 06:25:15 +08:00
if ( ! fileInfo . exists ( ) ) {
2013-11-14 18:40:39 +08:00
ui - > statusBar - > showMessage ( tr ( " Please select existing file " ) ) ;
2013-10-08 15:07:03 +08:00
return ;
}
QFile inputFile ;
inputFile . setFileName ( path ) ;
2013-11-23 06:25:15 +08:00
if ( ! inputFile . open ( QFile : : ReadOnly ) ) {
2013-11-07 21:46:28 +08:00
ui - > statusBar - > showMessage ( tr ( " Can't open file for reading " ) ) ;
2013-10-08 15:07:03 +08:00
return ;
}
QByteArray buffer = inputFile . readAll ( ) ;
inputFile . close ( ) ;
init ( ) ;
2014-01-15 04:09:18 +08:00
UINT8 result = ffsEngine - > parseImageFile ( buffer ) ;
2013-12-05 04:27:12 +08:00
showMessages ( ) ;
if ( result )
2013-11-14 18:40:39 +08:00
ui - > statusBar - > showMessage ( tr ( " Opened file can't be parsed (%1) " ) . arg ( result ) ) ;
2013-10-08 15:07:03 +08:00
else
ui - > statusBar - > showMessage ( tr ( " Opened: %1 " ) . arg ( fileInfo . fileName ( ) ) ) ;
2013-11-17 19:13:37 +08:00
2013-12-29 23:13:46 +08:00
// Enable search
ui - > actionSearch - > setEnabled ( true ) ;
2013-12-05 04:27:12 +08:00
}
void UEFITool : : clearMessages ( )
{
2013-12-29 23:13:46 +08:00
ffsEngine - > clearMessages ( ) ;
messageItems . clear ( ) ;
ui - > messageListWidget - > clear ( ) ;
2013-10-08 15:07:03 +08:00
}
void UEFITool : : dragEnterEvent ( QDragEnterEvent * event )
{
if ( event - > mimeData ( ) - > hasFormat ( " text/uri-list " ) )
2014-01-12 07:02:54 +08:00
event - > acceptProposedAction ( ) ;
2013-10-08 15:07:03 +08:00
}
void UEFITool : : dropEvent ( QDropEvent * event )
{
QString path = event - > mimeData ( ) - > urls ( ) . at ( 0 ) . toLocalFile ( ) ;
openImageFile ( path ) ;
}
2013-12-05 04:27:12 +08:00
void UEFITool : : showMessages ( )
2013-11-15 18:48:14 +08:00
{
2013-11-17 17:01:11 +08:00
ui - > messageListWidget - > clear ( ) ;
2013-12-05 04:27:12 +08:00
if ( ! ffsEngine )
return ;
2013-11-17 19:13:37 +08:00
2013-12-05 04:27:12 +08:00
messageItems = ffsEngine - > messages ( ) ;
2013-11-17 17:01:11 +08:00
for ( int i = 0 ; i < messageItems . count ( ) ; i + + ) {
2013-11-17 19:13:37 +08:00
ui - > messageListWidget - > addItem ( new MessageListItem ( messageItems . at ( i ) ) ) ;
2013-11-15 18:48:14 +08:00
}
}
void UEFITool : : scrollTreeView ( QListWidgetItem * item )
{
2013-11-17 17:01:11 +08:00
MessageListItem * messageItem = ( MessageListItem * ) item ;
QModelIndex index = messageItem - > index ( ) ;
2013-12-29 23:13:46 +08:00
if ( index . isValid ( ) ) {
ui - > structureTreeView - > scrollTo ( index ) ;
2013-11-17 17:01:11 +08:00
ui - > structureTreeView - > selectionModel ( ) - > clearSelection ( ) ;
2013-11-15 18:48:14 +08:00
ui - > structureTreeView - > selectionModel ( ) - > select ( index , QItemSelectionModel : : Select ) ;
}
2013-11-20 10:08:39 +08:00
}
2013-11-23 06:25:15 +08:00
2013-12-05 04:27:12 +08:00
void UEFITool : : contextMenuEvent ( QContextMenuEvent * event )
2013-11-23 06:25:15 +08:00
{
2013-12-05 04:27:12 +08:00
if ( ui - > messageListWidget - > underMouse ( ) ) {
2013-12-29 23:13:46 +08:00
ui - > menuMessages - > exec ( event - > globalPos ( ) ) ;
2013-12-05 04:27:12 +08:00
return ;
2013-12-29 23:13:46 +08:00
}
if ( ! ui - > structureTreeView - > underMouse ( ) )
return ;
QPoint pt = event - > pos ( ) ;
2013-12-05 04:27:12 +08:00
QModelIndex index = ui - > structureTreeView - > indexAt ( ui - > structureTreeView - > viewport ( ) - > mapFrom ( this , pt ) ) ;
if ( ! index . isValid ( ) )
return ;
2013-11-23 06:25:15 +08:00
2013-12-29 23:13:46 +08:00
TreeModel * model = ffsEngine - > treeModel ( ) ;
switch ( model - > type ( index ) )
2013-12-05 04:27:12 +08:00
{
2013-12-29 23:13:46 +08:00
case Capsule :
2013-12-05 04:27:12 +08:00
ui - > menuCapsuleActions - > exec ( event - > globalPos ( ) ) ;
break ;
2013-12-29 23:13:46 +08:00
case Image :
2013-12-05 04:27:12 +08:00
ui - > menuImageActions - > exec ( event - > globalPos ( ) ) ;
break ;
2013-12-29 23:13:46 +08:00
case Region :
2013-12-05 04:27:12 +08:00
ui - > menuRegionActions - > exec ( event - > globalPos ( ) ) ;
break ;
2013-12-29 23:13:46 +08:00
case Padding :
2013-12-05 04:27:12 +08:00
ui - > menuPaddingActions - > exec ( event - > globalPos ( ) ) ;
break ;
2013-12-29 23:13:46 +08:00
case Volume :
2013-12-05 04:27:12 +08:00
ui - > menuVolumeActions - > exec ( event - > globalPos ( ) ) ;
break ;
2013-12-29 23:13:46 +08:00
case File :
2013-12-05 04:27:12 +08:00
ui - > menuFileActions - > exec ( event - > globalPos ( ) ) ;
break ;
2013-12-29 23:13:46 +08:00
case Section :
2013-12-05 04:27:12 +08:00
ui - > menuSectionActions - > exec ( event - > globalPos ( ) ) ;
break ;
}
}
void UEFITool : : readSettings ( )
{
2014-01-11 17:20:58 +08:00
QSettings settings ( this ) ;
2013-12-29 23:13:46 +08:00
resize ( settings . value ( " mainWindow/size " , QSize ( 800 , 600 ) ) . toSize ( ) ) ;
2013-12-05 04:27:12 +08:00
move ( settings . value ( " mainWindow/position " , QPoint ( 0 , 0 ) ) . toPoint ( ) ) ;
2013-12-29 23:13:46 +08:00
QList < int > horList , vertList ;
horList . append ( settings . value ( " mainWindow/treeWidth " , 600 ) . toInt ( ) ) ;
horList . append ( settings . value ( " mainWindow/infoWidth " , 180 ) . toInt ( ) ) ;
vertList . append ( settings . value ( " mainWindow/treeHeight " , 400 ) . toInt ( ) ) ;
vertList . append ( settings . value ( " mainWindow/messageHeight " , 180 ) . toInt ( ) ) ;
ui - > infoSplitter - > setSizes ( horList ) ;
ui - > messagesSplitter - > setSizes ( vertList ) ;
ui - > structureTreeView - > setColumnWidth ( 0 , settings . value ( " tree/columnWidth0 " , ui - > structureTreeView - > columnWidth ( 0 ) ) . toInt ( ) ) ;
ui - > structureTreeView - > setColumnWidth ( 1 , settings . value ( " tree/columnWidth1 " , ui - > structureTreeView - > columnWidth ( 1 ) ) . toInt ( ) ) ;
ui - > structureTreeView - > setColumnWidth ( 2 , settings . value ( " tree/columnWidth2 " , ui - > structureTreeView - > columnWidth ( 2 ) ) . toInt ( ) ) ;
ui - > structureTreeView - > setColumnWidth ( 3 , settings . value ( " tree/columnWidth3 " , ui - > structureTreeView - > columnWidth ( 3 ) ) . toInt ( ) ) ;
2013-12-05 04:27:12 +08:00
}
void UEFITool : : writeSettings ( )
{
2014-01-11 17:20:58 +08:00
QSettings settings ( this ) ;
2013-12-29 23:13:46 +08:00
settings . setValue ( " mainWindow/size " , size ( ) ) ;
settings . setValue ( " mainWindow/position " , pos ( ) ) ;
settings . setValue ( " mainWindow/treeWidth " , ui - > structureGroupBox - > width ( ) ) ;
settings . setValue ( " mainWindow/infoWidth " , ui - > infoGroupBox - > width ( ) ) ;
settings . setValue ( " mainWindow/treeHeight " , ui - > structureGroupBox - > height ( ) ) ;
settings . setValue ( " mainWindow/messageHeight " , ui - > messageGroupBox - > height ( ) ) ;
settings . setValue ( " tree/columnWidth0 " , ui - > structureTreeView - > columnWidth ( 0 ) ) ;
settings . setValue ( " tree/columnWidth1 " , ui - > structureTreeView - > columnWidth ( 1 ) ) ;
settings . setValue ( " tree/columnWidth2 " , ui - > structureTreeView - > columnWidth ( 2 ) ) ;
settings . setValue ( " tree/columnWidth3 " , ui - > structureTreeView - > columnWidth ( 3 ) ) ;
2013-12-05 18:53:24 +08:00
}