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