1 /***********************************(GPL)******************************** 2 * wxHexEditor is a hex edit tool for editing massive files in Linux * 3 * Copyright (C) 2010 Erdem U. Altinyurt * 4 * * 5 * This program is free software; you can redistribute it and/or * 6 * modify it under the terms of the GNU General Public License * 7 * as published by the Free Software Foundation; either version 2 * 8 * of the License. * 9 * * 10 * This program is distributed in the hope that it will be useful, * 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 13 * GNU General Public License for more details. * 14 * * 15 * You should have received a copy of the GNU General Public License * 16 * along with this program; * 17 * if not, write to the Free Software Foundation, Inc., * 18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * 19 * * 20 * home : www.wxhexeditor.org * 21 * email : spamjunkeater@gmail.com * 22 *************************************************************************/ 23 24 25 #ifndef _wxHexEditor_h_ 26 #define _wxHexEditor_h_ 27 28 typedef bool _Bool; 29 #include <mhash.h> 30 31 #include <wx/ffile.h> 32 #include <wx/clipbrd.h> 33 #include <wx/numdlg.h> 34 #include <wx/version.h> 35 #include <wx/progdlg.h> 36 37 #include "FAL.h" 38 #include "HexPanels.h" 39 #include "HexEditorGui.h" 40 #include "HexEditorCtrl/HexEditorCtrl.h" 41 #include "HexDialogs.h" 42 43 #if wxCHECK_VERSION( 2,9,0 ) && !defined(__WXMAC__) && !defined( __WXMSW__) 44 //Only GTK port is working good on detect changes of file. 45 //MSW cannot detect changes in individual files yet in wxWidgets 3.1.0 46 #define _FSWATCHER_ 1 47 #include <wx/fswatcher.h> 48 #else 49 #define _FSWATCHER_ 0 50 #endif 51 52 #define idInjection 3000 53 #define idBlockSelect 3001 54 55 #define MB (1024*1024) //this utility uses old ECS format. 56 57 class scrollthread; 58 class copy_maker; 59 60 class HexEditor: public HexEditorCtrl 61 /*, protected FAL*/ 62 { 63 public: 64 HexEditor(wxWindow* parent, 65 int id, 66 wxStatusBar *statusbar=NULL, 67 DataInterpreter *interpreter=NULL, 68 InfoPanel *infopanel=NULL, 69 TagPanel *tagpanel=NULL, 70 DisassemblerPanel *dasmpanel=NULL, 71 wxFileName* myfile=NULL, 72 const wxPoint& pos=wxDefaultPosition, 73 const wxSize& size=wxDefaultSize, 74 long style=0); 75 ~HexEditor( void ); 76 friend class scrollthread; 77 friend class ChecksumDialog; 78 79 HexEditor *ComparatorHexEditor; 80 void Goto( int64_t goto_offset, bool set_focus=false ); 81 void OnOffsetScroll(wxScrollEvent &event); 82 void LoadFromOffset(int64_t position, bool cursor_reset=false, bool paint=true, bool from_comparator=false ); //loads file from position 83 void Reload(); //loads file from current page offset; refresh 84 void ReDraw(); 85 void ThreadPaint(wxCommandEvent& event); //This class created for remove scroolthread update functions with MutexGui Lock mechanism. 86 87 bool IsFileUsingXORKey( void ); 88 void FileSetXORKey( bool enable ); 89 wxString FileGetXORKey( void ); 90 bool FileOpen( wxFileName& filename ); 91 bool FileReOpen( void ); 92 bool FileSave( bool question = true ); 93 bool FileSave( wxString filename ); 94 bool FileClose( bool WithoutChange = false ); 95 bool SaveAsDump( void ); 96 bool FillSelection( void ); 97 void BlockSelect( void ); 98 void DoUndo( void ); 99 void DoRedo( void ); 100 101 bool CutSelection( void ); 102 bool DeleteSelection( void ); 103 bool InsertBytes( void ); 104 bool CopySelection( void ); 105 bool PasteFromClipboard( void ); 106 107 //----File Functions----// FileLength(void)108 int64_t FileLength( void ) { 109 //if( myfile->IsProcess() ) 110 // return ProcessRAMMap.Last(); 111 return myfile->Length(); 112 } 113 bool FileAddDiff( int64_t start_byte, const char* data, int64_t size, bool extension = false ); //adds new node GetFileName(void)114 wxFileName GetFileName( void ) { 115 return myfile->GetFileName(); 116 } SetFileAccessMode(FAL::FileAccessMode fam)117 bool SetFileAccessMode( FAL::FileAccessMode fam ) { 118 return myfile->SetAccessMode( fam ); 119 } GetFileAccessMode(void)120 int GetFileAccessMode( void ) { 121 return myfile->GetAccessMode(); 122 } GetFileAccessModeString(void)123 wxString GetFileAccessModeString( void ) { 124 return myfile->GetAccessModeString(); 125 } IsBlockDevice(void)126 bool IsBlockDevice( void ){ 127 return myfile->GetBlockSize() > 0; 128 } GetFD(void)129 int GetFD( void ) { 130 return myfile->fd(); 131 } IsAvailable_Undo(void)132 bool IsAvailable_Undo( void ) { 133 return myfile->IsAvailable_Undo(); 134 } IsAvailable_Redo(void)135 bool IsAvailable_Redo( void ) { 136 return myfile->IsAvailable_Redo(); 137 } 138 int HashVerify(wxString hash_file,FAL* File=NULL); 139 140 void FindDialog( void ); 141 void ReplaceDialog( void ); 142 void CopyAsDialog( void ); 143 void GotoDialog( void ); 144 145 void UpdateCursorLocation( bool force=false ); 146 void ConnectScroll(HexEditor* connection); 147 void DisconnectScroll( void ); 148 149 #if _FSWATCHER_ 150 void OnFileModify(wxFileSystemWatcherEvent &event); 151 #endif // _FSWATCHER_ 152 153 protected: 154 void SetLocalHexInsertionPoint( int hex_location, bool from_comparator=false ); 155 void OnKeyboardChar(wxKeyEvent& event); 156 void OnKeyboardInput(wxKeyEvent& event); 157 void OnKeyboardSelector( wxKeyEvent& event ); 158 void OnKeyboardSelectionEnd( wxKeyEvent& event ); 159 void OnMouseTest( wxMouseEvent& event ); 160 void OnMouseLeft( wxMouseEvent& event ); 161 void OnMouseRight( wxMouseEvent& event ); 162 void OnMouseSelectionEnd( wxMouseEvent& event ); 163 void OnMouseMove( wxMouseEvent& event ); 164 void OnMouseWhell( wxMouseEvent& event ); 165 void OnOffsetMouse( wxMouseEvent& event ); 166 void OnResize( wxSizeEvent &event ); 167 void OnUpdateUI( wxUpdateUIEvent& event ); 168 169 void ShowContextMenu( const wxMouseEvent& event ); 170 void ScrollNoThread( int speed ); 171 172 wxStatusBar* statusbar; 173 FAL *myfile; 174 #ifndef DO_NOT_USE_THREAD_FOR_SCROLL 175 scrollthread *myscrollthread; 176 #endif 177 DataInterpreter *interpreter; 178 InfoPanel *infopanel; 179 TagPanel *tagpanel; 180 DisassemblerPanel *dasmpanel; 181 copy_maker *copy_mark; 182 183 private: 184 int64_t BlockSelectOffset; 185 bool MouseCapture; 186 void Dynamic_Connector( void ); 187 void Dynamic_Disconnector( void ); 188 }; 189 190 class copy_maker { 191 public: 192 bool copied; //copy in action or not 193 int64_t start; //copy start position 194 int64_t size; //size of copy 195 wxMemoryBuffer m_buffer; //uses RAM, for small data 196 //wxFile *tempfile; //uses Temp HDD File and delete after. 197 FAL *sourcefile; //uses HDD File and NOT delete after. copy_maker()198 copy_maker( ) { 199 copied = false; 200 start = size = 0; 201 // tempfile = NULL; 202 sourcefile = NULL; 203 } ~copy_maker()204 ~copy_maker( ) { 205 //if(tempfile != NULL) 206 //if(sourcefile != NULL) 207 } SetClipboardData(wxString & CopyString)208 bool SetClipboardData( wxString& CopyString) { 209 if(wxTheClipboard->Open()) { 210 // if (wxTheClipboard->IsSupported( wxDF_TEXT )){ 211 wxTheClipboard->Clear(); 212 int isok = wxTheClipboard->SetData( new wxTextDataObject( CopyString )); 213 wxTheClipboard->Flush(); 214 wxTheClipboard->Close(); 215 return isok; 216 } 217 else { 218 wxMessageBox( wxString(_( "Clipboard could not be opened.")) + wxT("\n") + _("Operation cancelled!"), _("Copy To Clipboard Error"), wxOK|wxICON_ERROR); 219 return false; 220 } 221 } 222 GetClipboardData(void)223 wxString GetClipboardData( void ) { 224 if(wxTheClipboard->Open()) { 225 if (wxTheClipboard->IsSupported( wxDF_TEXT )) { 226 wxTextDataObject data; 227 wxTheClipboard->GetData( data ); 228 wxTheClipboard->Close(); 229 return data.GetText(); 230 } 231 else { 232 wxBell(); 233 wxTheClipboard->Close(); 234 return wxString(); 235 } 236 } 237 else { 238 wxMessageBox( wxString(_( "Clipboard could not be opened.")) + wxT("\n") + _("Operation cancelled!"), _("Copy To Clipboard Error"), wxOK|wxICON_ERROR); 239 return wxString(); 240 } 241 } 242 }; 243 244 class scrollthread:wxThreadHelper { 245 private: 246 HexEditor *parent; 247 int speed; 248 wxMutex speed_mtx; 249 public: 250 wxMutex ThreadScrool; scrollthread(int initial_speed,HexEditor * parent)251 scrollthread(int initial_speed, HexEditor *parent ):parent(parent) { 252 speed = initial_speed; 253 #if wxCHECK_VERSION(2,9,0) 254 CreateThread(); 255 #else 256 Create(); 257 #endif 258 GetThread()->Run(); 259 if(speed == 0) 260 GetThread()->Pause(); 261 } 262 Entry()263 void *Entry() { 264 int64_t newoffset=0; 265 int64_t FileLength; 266 int thread_speed; 267 ThreadScrool.Unlock(); 268 while( !(GetThread()->TestDestroy()) ) { 269 speed_mtx.Lock(); 270 thread_speed=speed; 271 speed_mtx.Unlock(); 272 if(speed == 0){ 273 wxMicroSleep( 25 ); 274 continue; // loop to "while" for init of class and wait for GetThread()->Pause(); 275 } 276 #if _DEBUG_THREAD_SCROLL_ 277 std::cout << "scrollthread speed : " << thread_speed; 278 #endif 279 FileLength = parent->FileLength(); 280 newoffset = parent->page_offset + ( parent->BytePerLine() )*thread_speed; 281 if( newoffset < 0 ) 282 newoffset = 0; 283 else if( newoffset + parent->ByteCapacity() >= FileLength ) { 284 newoffset = FileLength - parent->ByteCapacity(); 285 newoffset += parent->BytePerLine() - (parent->page_offset % parent->BytePerLine()) ; //cosmetic 286 } 287 #if _DEBUG_THREAD_SCROLL_ 288 std::cout << " \t- offset : " << newoffset << std::endl; 289 #endif 290 if( newoffset != parent->page_offset ){ 291 parent->page_offset=newoffset; 292 293 while( ThreadScrool.TryLock() != wxMUTEX_NO_ERROR ) 294 GetThread()->Sleep(25); 295 296 wxCommandEvent event( wxEVT_COMMAND_TEXT_UPDATED, THREAD_UPDATE_EVENT ); 297 //event.SetWillBeProcessedAgain(); 298 //event.SetInt(n); // pass some data along the event, a number in this case 299 ::wxPostEvent( parent, event ); 300 wxYieldIfNeeded(); 301 } 302 } 303 #if _DEBUG_THREAD_SCROLL_ 304 std::cout << "scrollthread got testDestroy!" << std::endl; 305 #endif 306 return NULL; 307 } 308 UpdateSpeed(int new_speed)309 void UpdateSpeed(int new_speed) { 310 #if _DEBUG_THREAD_SCROLL_ 311 std::cout << "UpdateSpeed:" << new_speed << std::endl; 312 #endif 313 if (new_speed == 0 && speed == 0 ) 314 return; 315 else if(new_speed == 0 && GetThread()->IsRunning() ) 316 GetThread()->Pause(); 317 else if( GetThread()->IsPaused() ) 318 GetThread()->Resume(); 319 320 speed_mtx.Lock(); 321 speed = new_speed; 322 speed_mtx.Unlock(); 323 } 324 Exit(void)325 void Exit(void){ 326 if( !GetThread()->IsRunning() ) //We can only "Delete" running threads 327 GetThread()->Resume();// Resume the thread for kill it 328 GetThread()->Delete(); 329 } 330 }; 331 332 333 334 #endif 335