aboutsummaryrefslogtreecommitdiff
path: root/src/hd24hexview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/hd24hexview.cpp')
-rwxr-xr-xsrc/hd24hexview.cpp923
1 files changed, 923 insertions, 0 deletions
diff --git a/src/hd24hexview.cpp b/src/hd24hexview.cpp
new file mode 100755
index 0000000..8ee4751
--- /dev/null
+++ b/src/hd24hexview.cpp
@@ -0,0 +1,923 @@
1#include <iostream>
2#include <algorithm>
3#include <cctype>
4#include <string>
5#include <sys/types.h>
6#include <sys/stat.h>
7#include <fcntl.h>
8#include <stdio.h>
9#include <stdlib.h>
10#include "config.h"
11#include "hd24fs.h"
12#include "convertlib.h"
13
14#define VERSION "1.3 beta"
15#define _LARGE_FILES
16#define _FILE_OFFSET_BITS 64
17#define FILE_OFFSET_BITS 64
18#define LARGE_FILES
19#define LARGEFILE64_SOURCE
20#define SECTORSIZE 512
21#define ARGHEADER "--header="
22
23#ifdef DARWIN
24# define open64 open
25# define lseek64 lseek
26# define pread64 pread
27# define creat64 creat
28# define pwrite64 pwrite
29#endif
30
31#ifndef WINDOWS
32# include <unistd.h>
33#endif
34
35string device;
36string headerfilename;
37__uint64 writeoffset;
38int force;
39int expertmode;
40int graphmode;
41int enable_graphmode;
42int disable_graphmode;
43
44// Check if a file exists
45bool fileexists (string* fname)
46{
47 struct stat fi;
48
49 if ((stat(fname->c_str(), &fi) != -1) && ((fi.st_mode & S_IFDIR) == 0)) {
50 return true;
51 }
52
53 return false;
54}
55
56// Check if file handle is invalid
57bool isinvalidhandle(FSHANDLE handle)
58{
59#ifdef WINDOWS
60 if (handle == FSHANDLE_INVALID) {
61 return true;
62 }
63#else
64 if (handle == 0 || handle == FSHANDLE_INVALID) {
65 return true;
66 }
67#endif
68 return false;
69}
70
71// Output a message for expert only features
72void expertmodemessage(string feature)
73{
74 cout << feature <<" is only allowed in expert mode." << endl;
75}
76
77// Seek to a position in the drive
78void hd24seek(FSHANDLE devhd24, __uint64 seekpos)
79{
80#ifdef WINDOWS
81 LARGE_INTEGER li;
82 li.HighPart = seekpos >> 32;
83 li.LowPart = seekpos % ((__uint64) 1 << 32);
84 SetFilePointerEx(devhd24, li, NULL, FILE_BEGIN);
85#else
86 lseek64(devhd24, seekpos, 0);
87#endif
88 return;
89}
90
91// Calculate a 32-bit checksum for a block
92long unsigned int calcblockchecksum(hd24raw* rawdevice, unsigned long firstsector, unsigned long endsector)
93{
94 long unsigned int checksum32 = 0;
95 unsigned char origblock[5120];
96
97 for (unsigned long k = firstsector; k < endsector; k++)
98 {
99 rawdevice->readsectors(k, origblock, 1);
100
101 for (unsigned long i = 0; i < SECTORSIZE; i += 4)
102 {
103 unsigned long num = Convert::getint32(origblock, i);
104 int byte1 = num % 256;
105 int byte2 = (num >> 8) % 256;
106 int byte3 = (num >> 16) % 256;
107 int byte4 = (num >> 24) % 256;
108 num = byte4 + (byte3 << 8) + (byte2 << 16) + (byte1 << 24);
109 checksum32 += num;
110 }
111 }
112
113 return checksum32;
114}
115
116// Write to a sector
117long writesectors(FSHANDLE devhd24, unsigned long sectornum, unsigned char * buffer, int sectors)
118{
119 int WRITESIZE = SECTORSIZE * sectors; // allows searching across sector boundaries
120 hd24seek(devhd24, (__uint64) sectornum * 512);
121
122#ifdef WINDOWS
123 DWORD dummy;
124 long bytes = 0;
125
126 if (WriteFile(devhd24, buffer, WRITESIZE, &dummy, NULL)) {
127 bytes = WRITESIZE;
128 };
129#else
130 long bytes = pwrite64(devhd24, buffer, WRITESIZE, (__uint64) sectornum * 512);
131#endif
132
133 return bytes;
134}
135
136void writetofile(hd24raw* rawdevice,string filename, long firstsector,long endsector)
137{
138 int i;
139 unsigned char bootblock[5120];
140#if defined(LINUX) || defined(DARWIN)
141 FSHANDLE handle=creat64(filename.c_str(),O_WRONLY);
142#endif
143#ifdef WINDOWS
144 FSHANDLE handle=CreateFile(filename.c_str(),GENERIC_WRITE|GENERIC_READ,
145 FILE_SHARE_READ|FILE_SHARE_WRITE,
146 NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
147 if (isinvalidhandle(handle)) {
148 handle=CreateFile(filename.c_str(),GENERIC_WRITE|GENERIC_READ,
149 FILE_SHARE_READ|FILE_SHARE_WRITE,
150 NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
151 }
152
153#endif
154 if (isinvalidhandle(handle)) {
155 cout << "Cannot open file "<<filename <<" for writing. Access denied?" << endl;
156 return;
157 }
158 cout << "Write range from offset "<< *Convert::int64tohex((__uint64)firstsector*512)<< " to offset " << *Convert::int64tohex((__uint64)endsector*512-1) << endl;
159 for (i=firstsector;i<endsector;i++) {
160 rawdevice->readsectors(i,bootblock,1);
161#if defined(LINUX) || defined(DARWIN)
162 __uint64 targetoff=i;
163 targetoff-=firstsector;
164 targetoff+=writeoffset;
165 targetoff*=512;
166 ssize_t byteswritten=pwrite64(handle,bootblock,512,targetoff);
167#endif
168#ifdef WINDOWS
169 //DWORD dummy;
170 //long bytes=0;
171 __uint64 targetoff=i;
172 targetoff-=firstsector;
173 targetoff+=writeoffset;
174 __uint64 byteswritten=writesectors(handle,targetoff,bootblock,1);
175#endif
176 if (byteswritten==0) {
177 cout << "Wrote 0 bytes to file. Access denied?" << endl;
178#if defined(LINUX) || defined(DARWIN)
179 close (handle);
180#endif
181#ifdef WNDOWS
182 CloseHandle(handle);
183#endif
184 return;
185 }
186 if ((i%1000)==0) {
187 string* x=Convert::int64tohex((__uint64)i*0x200);
188 cout << "Write offset " << *x << "\r";
189 if (x!=NULL) { delete x; x=NULL; }
190 }
191 }
192#if defined(LINUX) || defined(DARWIN)
193 close (handle);
194#endif
195#ifdef WINDOWS
196 CloseHandle(handle);
197#endif
198 return;
199}
200
201string getbinstr(string tofind)
202{
203 if (tofind.substr(0,1)=="'") {
204 // find literal string
205 tofind=tofind.substr(1,tofind.length()-2);
206 cout << "Find string " << tofind << endl;
207 } else {
208 string binstr="";
209 string tmp="";
210 tofind+=" ";
211 unsigned int i;
212 for (i=0;i<tofind.length();i++) {
213 string onechar=tofind.substr(i,1);
214 if (onechar!=" ") {
215 if (!Convert::isnibble(onechar)) {
216 cout << "Error: not a valid hex string" << endl;
217 return "";
218 }
219 tmp+=onechar;
220 } else {
221 if (tmp!="") {
222 binstr+=Convert::hex2byte(tmp);
223 }
224 tmp="";
225 }
226 }
227 tofind=binstr;
228 cout << "looking for " << binstr << endl;
229 }
230 return *(new string(tofind));
231}
232
233long movebytes(unsigned char* bootblock,string editstr)
234{
235 string strfrompos="";
236 string strmovelen="";
237 string strtopos="";
238 while (
239 (editstr.substr(0,1)!=" ")
240 &&(editstr.substr(0,1)!="l")
241 &&(editstr.substr(0,1)!="L")
242 &&(editstr!=""))
243 {
244 strfrompos+=editstr.substr(0,1);
245 editstr=editstr.substr(1,editstr.length()-1);
246 }
247 if (
248 (editstr.substr(0,1)=="l")
249 ||(editstr.substr(0,1)=="L"))
250 {
251 editstr=editstr.substr(1,editstr.length()-1);
252
253 while (
254 (editstr.substr(0,1)!=" ")
255 &&(editstr!=""))
256 {
257 strmovelen+=editstr.substr(0,1);
258 editstr=editstr.substr(1,editstr.length()-1);
259 }
260 } else {
261 cout << "Syntax: m<from>L<len> <target>" << endl;
262 return 0;
263 }
264
265 if (
266 (editstr.substr(0,1)==" ")
267 )
268 {
269 editstr=editstr.substr(1,editstr.length()-1);
270
271 while (
272 (editstr.substr(0,1)!=" ")
273 &&(editstr!=""))
274 {
275 strtopos+=editstr.substr(0,1);
276 editstr=editstr.substr(1,editstr.length()-1);
277 }
278 } else {
279 cout << "Syntax: m<from>L<len> <target>" << endl;
280 return 0;
281 }
282 cout << " strfrompos=" << strfrompos << endl;
283 cout << " strmovelen=" << strmovelen << endl;
284 cout << " strtopos=" << strtopos << endl;
285
286 long frompos=(Convert::hex2long(strfrompos)%SECTORSIZE);
287 long movelen=(Convert::hex2long(strmovelen)%SECTORSIZE);
288 long topos=(Convert::hex2long(strtopos)%SECTORSIZE);
289 cout << " pos=" << frompos << endl;
290 cout << " movelen=" << movelen << endl;
291 cout << " movepos=" << topos << endl;
292 void* x=malloc(movelen);
293 memcpy(x,bootblock+frompos,movelen);
294 memcpy(bootblock+topos,x,movelen);
295 free (x);
296 return 0;
297}
298
299long editbytes(unsigned char* bootblock,string editstr)
300{
301 string strpos="";
302 while ((editstr.substr(0,1)!=" ") &&(editstr!="")) {
303 strpos+=editstr.substr(0,1);
304 editstr=editstr.substr(1,editstr.length()-1);
305 }
306 if (editstr!="") {
307 editstr=editstr.substr(1,editstr.length()-1);
308 }
309 string binstr=getbinstr(editstr);
310 long pos=(Convert::hex2long(strpos)%SECTORSIZE);
311 cout << "binstr=" << binstr << " " << pos << endl;
312 memcpy(bootblock+pos,binstr.c_str(),binstr.length());
313 return 0;
314}
315
316void compareblock(hd24raw* rawdevice,unsigned long firstsector,unsigned long endsector,long current)
317{
318 unsigned int i;
319 unsigned int j;
320 unsigned int k;
321 unsigned char origblock[5120];
322 unsigned char destblock[5120];
323 string* startoff=Convert::int64tohex((__uint64)firstsector*512);
324 string* endoff=Convert::int64tohex((__uint64)endsector*512-1);
325 cout << "Compare range from offset "<< *startoff << " to offset " << *endoff <<endl;
326 delete startoff; startoff=NULL;
327 delete endoff; endoff=NULL;
328 int anydifs=0;
329 for (k=firstsector; k<endsector; k++)
330 {
331 rawdevice->readsectors(k,origblock,1);
332 rawdevice->readsectors(k-firstsector+current,destblock,1);
333 for (i=0;i<SECTORSIZE;i+=16) {
334 string strline1="";
335 string strline2="";
336 int havedifs=0;
337 long offset=k*512;
338 string* result1=Convert::int32tohex(offset+i);
339 strline1+= *result1+" ";
340 offset=current*512;
341 delete result1; result1=NULL;
342 string* result2=Convert::int32tohex(offset+i);
343 strline2+= *result2+" ";
344 delete result2; result2=NULL;
345 for (j=0;j<16;j++)
346 {
347 if (origblock[i+j]!=destblock[i+j])
348 {
349 string* result=Convert::byte2hex(origblock[i+j]);
350 strline1+= *result;
351 delete result; result=NULL;
352 havedifs=1;
353 } else {
354 strline1+=" ";
355 }
356 string *result= Convert::byte2hex(destblock[i+j]) ;
357 strline2+= *result;
358 delete result; result=NULL;
359 if (j==7) {
360 strline1+= "-" ;
361 strline2+= "-" ;
362 } else {
363 strline1+= " " ;
364 strline2+= " " ;
365 }
366 }
367 strline1+= " ";
368 strline2+= " ";
369 for (j=0;j<16;j++) {
370 strline1+= Convert::safebyte(origblock[i+j]);
371 if (origblock[i+j]!=destblock[i+j]) {
372 strline2+= Convert::safebyte(destblock[i+j]);
373 } else {
374 strline2+=" ";
375 }
376 }
377 if (havedifs==1) {
378 anydifs=1;
379 cout << strline1 << endl;
380 cout << strline2 << endl;
381 }
382 }
383 }
384 if (anydifs==0) {
385 cout << "Blocks are equal." << endl;
386 }
387}
388
389long scanforblock(hd24raw* rawdevice,string tofind,unsigned long firstsector,unsigned long endsector,long current)
390{
391 unsigned int i;
392 unsigned char bootblock[5120];
393 tofind=getbinstr(tofind);
394 if (tofind=="") return current;
395
396 /* Now that we know what to look for, let us try to find the string.
397 * Note that we can search across sector boundaries because we read
398 * 2 sectors at a time.
399 */
400 string* startoff= Convert::int64tohex((__uint64)firstsector*512);
401 string* endoff=Convert::int64tohex((__uint64)endsector*512-1);
402 cout << "Scan range from offset "<< *startoff << " to offset " << *endoff << endl;
403 delete startoff; startoff=NULL;
404 delete endoff; endoff=NULL;
405 for (i=firstsector; i<endsector; i++) {
406 rawdevice->readsectors(i,bootblock,2);
407 if ((i%0x1000)==0) {
408 string* curroff=Convert::int64tohex((__uint64)i*0x200);
409 cout << "Scan offset " << *curroff << "\r";
410 delete curroff; curroff=NULL;
411 }
412 /* check if string found. */
413 int j=0;
414 for (j=0;j<512;j++) {
415
416 if (memcmp((const void *)&bootblock[j],(const void *)tofind.c_str(),(size_t)tofind.length())==0) {
417 string* foundoff=Convert::int64tohex((__uint64)i*512+j);
418 cout << endl << "Found on offset " << *foundoff << endl;
419 delete foundoff; foundoff=NULL;
420 return i;
421 }
422 }
423 }
424 cout << endl << "Not found." << endl;
425 return current;
426}
427
428void fstfix(unsigned char * bootblock,int fixsize)
429{
430 for (int i=0;i<fixsize;i+=4)
431 {
432 unsigned char a=bootblock[i];
433 unsigned char b=bootblock[i+1];
434 unsigned char c=bootblock[i+2];
435 unsigned char d=bootblock[i+3];
436 bootblock[i]=d;
437 bootblock[i+1]=c;
438 bootblock[i+2]=b;
439 bootblock[i+3]=a;
440 }
441}
442
443int parsecommandline(int argc, char ** argv)
444{
445 int invalid=0;
446 force=0;
447 expertmode=0;
448 device="";
449 headerfilename="";
450 for (int c=1;c<argc;c++) {
451 string arg=argv[c];
452 if (arg.substr(0,2)!="--") {
453 if (fileexists(&arg)) {
454 device=arg;
455 force=1;
456 continue;
457 }
458 }
459 if (arg.substr(0,strlen("--dev="))=="--dev=") {
460 device=arg.substr(strlen("--dev="));
461 continue;
462 }
463 if (arg.substr(0,strlen("--expert"))=="--expert") {
464 expertmode=1;
465 continue;
466 }
467 if (arg.substr(0,strlen(ARGHEADER))==ARGHEADER) {
468 headerfilename=arg.substr(strlen(ARGHEADER));
469 continue;
470 }
471
472 if (arg.substr(0,strlen("--force"))=="--force") {
473 force=1;
474 continue;
475 }
476 cout << "Invalid argument: " << arg << endl;
477 invalid=1;
478 }
479 return invalid;
480}
481
482int main (int argc,char ** argv)
483{
484 int invalid=parsecommandline(argc,argv);
485 if (invalid!=0) {
486 return invalid;
487 }
488
489 hd24fs* fsys = NULL;
490 if (device=="") {
491 fsys=new hd24fs((const char*)NULL,hd24fs::MODE_RDWR);
492 } else {
493 cout << "Trying to use " << device << " as hd24 device." << endl;
494 fsys=new hd24fs((const char*)NULL,hd24fs::MODE_RDWR,&device,(force==1));
495 }
496
497 hd24raw* rawdevice = NULL;
498
499 rawdevice=new hd24raw(fsys); //1==1 is true -> no translate
500 if (!fsys->isOpen()) {
501 cout << "Cannot open hd24 device." << endl;
502 delete fsys; fsys=NULL;
503 if (rawdevice!=NULL)
504 {
505 delete rawdevice;
506 rawdevice=NULL;
507 }
508 return 1;
509 }
510 if (headerfilename!="")
511 {
512 if (!(fsys->useheaderfile(headerfilename)))
513 {
514 cout << "Couldn't load header file "<<headerfilename << endl;
515 delete fsys; fsys=NULL;
516 return 1;
517 };
518 }
519 //delete fsys; //not yet, rawdevice is using this
520 cout << "Using device " << *fsys->getdevicename() << endl;
521 /* Initialization */
522 unsigned char bootblock[5120];
523 unsigned long sectornum=0;
524 int nodump=0;
525 int noread=0;
526 int writesec=0;
527 unsigned long blockstart=0;
528 unsigned long blockend=0;
529 writeoffset=0;
530 unsigned long checksum=0;
531 string userinput;
532 string lastsearch="";
533 if (expertmode==1) {
534 cout << "Expert mode enabled. " << endl;
535 cout << "Warning! Disk writes are enabled." << endl;
536 cout << "You now have the capability to destroy." << endl;
537 cout << "Proceed with extreme caution!" << endl;
538 }
539
540try{
541 /* try block is intended to make sure hd24 device is closed on exit*/
542 string filename="outfile.dmp";
543
544 do {
545 int i;
546 int j;
547 if (enable_graphmode==1)
548 {
549 cout << "Enabling graph mode." << endl;
550 graphmode=1;
551 enable_graphmode=0;
552 }
553 if (disable_graphmode==1) {
554 cout << "Disabling graph mode." << endl;
555 graphmode=0;
556 disable_graphmode=0;
557 }
558 if (writesec==1) {
559 rawdevice->writesectors(sectornum,bootblock,1);
560 writesec=0;
561 }
562 if (noread==0) {
563 rawdevice->readsectors(sectornum,bootblock,1);
564 }
565 noread=0;
566 long offset=sectornum*512;
567 if (nodump==0) {
568 cout << "Sector " << *Convert::int32tohex((long)sectornum) << endl;
569
570 for (i=0;i<SECTORSIZE;i+=16) {
571 string* dummy=Convert::int32tohex(offset+i);
572 cout << *dummy << " ";
573 delete dummy; dummy=NULL;
574 for (j=0;j<16;j++) {
575 string* dummy= Convert::byte2hex(bootblock[i+j]);
576 cout << *dummy;
577 if (j==7) {
578 cout << "-" ;
579 } else {
580 cout << " " ;
581 }
582 delete dummy; dummy=NULL;
583 }
584 cout << " ";
585 for (j=0;j<16;j++) {
586 cout << Convert::safebyte(bootblock[i+j]);
587 }
588 cout << "" << endl;
589 }
590 }
591 nodump=0;
592 cout << "-";
593 char inputbuf[1025];
594 cin.getline(inputbuf,1024);
595 userinput="";
596 userinput+=inputbuf;
597 if (userinput=="") {
598 continue;
599 }
600 while (
601 (userinput.substr(userinput.length()-1,1)==" ")
602 ||(userinput.substr(userinput.length()-1,1)=="\n")
603 ||(userinput.substr(userinput.length()-1,1)=="\r")
604 )
605 {
606 userinput=userinput.substr(0,userinput.length()-1);
607 }
608 if (userinput=="+") {
609 sectornum++;
610 continue;
611 }
612 if (userinput=="gon") {
613 if (graphmode==0) {
614 enable_graphmode=1;
615 }
616 continue;
617 }
618 if ((userinput=="goff")||(userinput=="gof")) {
619 if (graphmode==1) {
620 disable_graphmode=1;
621 }
622 continue;
623 }
624 if (userinput=="wo") {
625 writeoffset=0;
626 cout << "Writeoffset cleared." << endl;
627 nodump=1; // inhibit viewing the sector after this command.
628 continue;
629 }
630 if (userinput.substr(0,2)=="wo") {
631 writeoffset=Convert::hex2long(userinput.substr(2,userinput.length()-2));
632 string* convwrite=Convert::int32tohex(writeoffset);
633 cout << "Writeoffset set to " << *convwrite << " sectors." << endl;
634 delete convwrite; convwrite=NULL;
635 nodump=1; // inhibit viewing the sector after this command.
636 continue;
637 }
638 if (userinput.substr(0,1)=="+") {
639 long sectoadd=Convert::hex2long(userinput.substr(1,userinput.length()-1));
640 sectornum+=sectoadd;
641 continue;
642 }
643 if (userinput=="-") {
644 if (sectornum>0)
645 {
646 sectornum--;
647 } else {
648 sectornum=0;
649 }
650 continue;
651 }
652 if (userinput.substr(0,1)=="-") {
653 long sectoadd=Convert::hex2long(userinput.substr(1,userinput.length()-1));
654 if ((__uint32)sectoadd>(__uint32)sectornum)
655 {
656 sectornum=0;
657 } else {
658 sectornum-=sectoadd;
659 }
660 continue;
661 }
662 if (userinput==".") {
663 noread=1;
664 continue;
665 }
666 if ((userinput.substr(0,1)=="?")||(userinput=="help")) {
667 cout << "Help for hd24hexview " << VERSION << endl;
668 cout << "==============================" << endl;
669 cout << "General:" <<endl;
670 cout << " q quit" << endl;
671 cout << " ? shows this help" << endl;
672 cout << endl;
673 cout << "Navigation:" << endl;
674 cout << " + dump next sector" << endl;
675 cout << " +<n> increment n sectors, then dump sector"<<endl;
676 cout << " - dump prev sector" << endl;
677 cout << " -<n> decrement n sectors, then dump sector"<<endl;
678 cout << " . re-display current sector" << endl;
679 cout << " d<hex> dump sector <hex>" << endl;
680 cout << " d-<hex> dump sector totalnumberofsectors-<hex>" << endl;
681 cout << " d re-read current sector from disk" << endl;
682 cout << " m<from>l<hexlen> <to>" << endl;
683 cout << " move <hexlen> bytes from offset <from> to <to>" << endl;
684 cout << " o<hex> dump sector that contains offset <hex>" << endl;
685 cout << " s x y.. scan marked block for byte sequence x y ..." << endl;
686 cout << " s'...' scan marked block for exact string" << endl;
687 cout << " e<p> xx edit byte sequence at pos p to xxxx " << endl;
688 cout << " e<p> 'x' edit pos p to string 'x'" << endl;
689 cout << endl;
690 cout << "Block commands:" << endl;
691 cout << " bb mark start of sector as block beginning" << endl;
692 cout << " be mark end of sector as block end" << endl;
693 cout << " bc block clear" << endl;
694 cout << " diff compare marked block with current" << endl;
695 cout << " p paste first sector of marked block to current sector" << endl;
696 cout << endl;
697 cout << "File commands:" << endl;
698 cout << " n<xx> set filename to xx" << endl;
699 cout << " n clear filename" << endl;
700 cout << " w write marked block to named file/device" << endl;
701 cout << " wo clear sector write offset for file/device write" << endl;
702 cout << " wo<xx> set write offset to xx sectors" << endl;
703 cout << " ws write back current edited sector to disk" << endl;
704 cout << "HD24 specific features:" << endl;
705 cout << " fix reverse byte ordering of 32 bit words" << endl;
706 cout << " for better human readability" << endl;
707 cout << " cs Calc checksum of selected block" << endl;
708 cout << " scs Set zero checksum of selected block" << endl;
709
710 nodump=1; // inhibit viewing the sector after this command.
711 continue;
712 }
713 if (userinput.substr(0,2)=="bc") {
714 blockstart=0;
715 blockend=0;
716 cout << "Block selection cleared." << endl;
717 nodump=1; // inhibit viewing the sector after this command.
718 continue;
719 }
720 if (userinput.substr(0,2)=="bb") {
721 cout << "Block start set." << endl;
722 nodump=1; // inhibit viewing the sector after this command.
723 blockstart=sectornum;
724 continue;
725 }
726 if (userinput.substr(0,2)=="be") {
727 cout << "Block end set." << endl;
728 /* dump is startsector..endsector,
729 * excl. end sector. number of bytes to dump=
730 * (blockend-blockstart)*512
731 */
732 nodump=1; // inhibit viewing the sector after this command.
733 blockend=sectornum+1;
734 continue;
735 }
736 if (userinput.substr(0,2)=="cs") {
737 checksum=calcblockchecksum(rawdevice,blockstart,blockend);
738 cout << "Block checksum is " << checksum << endl;
739 nodump=1;
740 noread=1;
741 continue;
742 }
743 if (userinput.substr(0,3)=="scs") {
744 if (blockend-1!=sectornum) {
745 cout << "Current sector must be block end." << endl;
746 nodump=1;
747 noread=1;
748 continue;
749 }
750 unsigned long checksum=calcblockchecksum(rawdevice,blockstart,blockend);
751 unsigned long oldchecksum=0;
752 oldchecksum+=((unsigned char)(bootblock[511])); oldchecksum=oldchecksum <<8;
753 oldchecksum+=((unsigned char)(bootblock[510])); oldchecksum=oldchecksum <<8;
754 oldchecksum+=((unsigned char)(bootblock[509])); oldchecksum=oldchecksum <<8;
755 oldchecksum+=((unsigned char)(bootblock[508]));
756 oldchecksum-=checksum;
757 bootblock[508]=oldchecksum%256; oldchecksum=oldchecksum >> 8;
758 bootblock[509]=oldchecksum%256; oldchecksum=oldchecksum >> 8;
759 bootblock[510]=oldchecksum%256; oldchecksum=oldchecksum >> 8;
760 bootblock[511]=oldchecksum%256; oldchecksum=oldchecksum >> 8;
761
762 noread=1;
763 continue;
764 }
765 if (userinput.substr(0,4)=="diff") {
766 nodump=1; // inhibit viewing the sector after this command.
767 if (blockend==blockstart) {
768 cout << "Please set block start/end first." << endl;
769 continue;
770 }
771 compareblock(rawdevice,blockstart,blockend,sectornum);
772 continue;
773 }
774 if (userinput.substr(0,1)=="s") {
775 if (userinput=="s") {
776 userinput+=lastsearch;
777 } else {
778 lastsearch=userinput.substr(1,userinput.length()-1);
779 }
780 if (blockend==blockstart) {
781 sectornum=scanforblock(rawdevice,lastsearch,0,0xffffffff,sectornum);
782 } else {
783 sectornum=scanforblock(rawdevice,lastsearch,blockstart,blockend,sectornum);
784 }
785 continue;
786 }
787 if (userinput=="version") {
788 cout << VERSION << endl;
789 nodump=1; // inhibit viewing the sector after this command.
790 noread=1;
791 continue;
792 }
793 if (userinput.substr(0,1)=="p") {
794 //paste
795 if (blockend==blockstart) {
796 nodump=1;
797 cout << "Mark a block first." << endl;
798 continue;
799 }
800 rawdevice->readsectors(blockstart,bootblock,1);
801 noread=1;
802 continue;
803 }
804 if (userinput.substr(0,1)=="e") {
805 string editstr=userinput.substr(1,userinput.length()-1);
806 editbytes(bootblock,editstr);
807 noread=1;
808 continue;
809 }
810 if (userinput.substr(0,1)=="m") {
811 string editstr=userinput.substr(1,userinput.length()-1);
812 movebytes(bootblock,editstr);
813 noread=1;
814 continue;
815 }
816 if (userinput=="d") {
817 continue;
818 }
819
820 if (userinput.substr(0,2)=="d-") {
821 // if we have 10 sectors (0..9), last one is d-1=sector 9
822 // so sector num is total number of secs - negnum
823 sectornum=rawdevice->getlastsectornum()-Convert::hex2long(userinput.substr(2,userinput.length()-2))+1;
824 continue;
825 }
826
827 if (userinput.substr(0,1)=="d") {
828 sectornum=Convert::hex2long(userinput.substr(1,userinput.length()-1));
829 continue;
830 }
831 if (userinput.substr(0,1)=="o") {
832 long offset=Convert::hex2long(userinput.substr(1,userinput.length()-1));
833 offset-=(offset%512);
834 sectornum=offset/512;
835 }
836 if (userinput=="fix") {
837 fstfix(bootblock,512);
838 noread=1;
839 continue;
840 }
841 if (userinput.substr(0,1)=="n") {
842 int dangerousname=0;
843 if (userinput.substr(1,4)=="\\\\.\\") {
844 dangerousname=1;
845 }
846 if (userinput.substr(1,5)=="/dev/") {
847 dangerousname=1;
848 }
849 if (userinput.substr(1,4)=="//./") {
850 dangerousname=1;
851 }
852 if (dangerousname==1) {
853 if (expertmode==0) {
854 expertmodemessage("Writing to devices");
855 } else {
856 filename=userinput.substr(1,userinput.length()-1);
857 cout << "OK, setting output file to device " << filename << endl;
858 cout << "Please take your time to make sure this is really the correct drive."<<endl;
859 string strlower=filename;
860 int (*pf)(int)=tolower;
861 std::transform (strlower.begin(),strlower.end(),strlower.begin(),pf);
862 if (
863 (strlower=="\\\\.\\physicaldrive0")
864 || (strlower=="/dev/hda"))
865 {
866 cout << "CAREFUL!!! " << strlower << " is probably your main system disk!" << endl;
867 cout << "If you continue you might mess up your computer!!!" << endl;
868 cout << "I will not stop you from doing this, so " << endl;
869 cout << "MAKE SURE THIS IS REALLY THE DRIVE YOU WANT TO WRITE TO!" << endl;
870 cout << "UNLESS ABSOLUTELY SURE, STOP WHAT YOU ARE DOING RIGHT NOW!" << endl;
871 }
872 }
873 } else {
874 filename=userinput.substr(1,userinput.length()-1);
875 }
876 nodump=1; // inhibit viewing the sector after this command.
877 if (filename=="") {
878 string filename="outfile.dmp";
879 }
880 cout << "Current output filename is " << filename << endl;
881
882 continue;
883 }
884 if (userinput=="w") {
885 cout << "Writing " << blockend-blockstart << " sectors to " << filename << endl;
886 writetofile(rawdevice,filename,blockstart,blockend);
887 nodump=1; // inhibit viewing the sector after this command.
888 cout << "Done." << endl;
889 continue;
890 }
891 if (userinput=="ws") {
892 if (expertmode==1) {
893 writesec=1;
894 } else {
895 noread=1;
896 expertmodemessage("Writing sectors");
897 nodump=1;
898 }
899 }
900 if (userinput=="freesec") {
901 nodump=1;
902 cout << "Sector " << *Convert::int32tohex((long)rawdevice->getnextfreesector(0xFFFFFFFF)) << endl;
903 cout << rawdevice->getnextfreesector(0xFFFFFFFF) << endl;
904 }
905 if (userinput=="commit") {
906 if (expertmode==1) {
907 cout << "Commit FS to disk." << endl;
908 fsys->commit();
909 }
910 }
911 } while (userinput!="q");
912
913} catch (string e) {
914 cout << "Exiting because of an unexpected error." << endl;
915 delete rawdevice; rawdevice=NULL;
916 delete fsys; fsys=NULL;
917 return 1;
918}
919 delete rawdevice; rawdevice=NULL;
920 delete fsys; fsys=NULL;
921 return 0;
922}
923