FAT12 img tool

NJU/2019/OS

Description:

 

 

 

CODE:

Main.cpp:

 

  1 /*
  2 @author: Edwin Xu
  3 @Date:2019/11/13
  4 @Note: just ASCII
  5 */
  6 #include <cstdio>
  7 #include <cstdlib>
  8 #include <cstring>
  9 #include <iostream>
 10 #include <string>
 11 #include <iostream>
 12 #include <vector>
 13 
 14 #define IMG_PATH "a.img"
 15 
 16 using namespace std;
 17 
 18 //myPrint in NASM
 19 extern "C" {void myPrint(char *c,int len,int color);}
 20 //print func using myPrint()
 21 char chars[513]; 
 22 void print(string s,int color){
 23     const char * c = s.c_str();
 24     strcpy(chars,s.c_str());
 25     myPrint(chars,s.length(),color);
 26 }
 27 
 28 
 29 
 30 //Part1: struct and util functions 
 31 struct File
 32 {
 33     string filename;
 34     int size;
 35     int firstCluster;
 36     File(string n, int s, int cluster) {
 37         filename = n;
 38         size = s;
 39         firstCluster = cluster;
 40     }
 41     File(){
 42         size = 0;
 43         filename = "";
 44         firstCluster = 0;
 45     }
 46 };
 47 struct Directory
 48 {
 49     string dirName ;
 50     //子目录
 51     vector <Directory>subDirs ;
 52     //当前文件夹的文件
 53     vector <File>subFiles ;
 54     int dirNum=0;
 55     int fileNum=0;
 56 
 57     void addDir(Directory d) {
 58         this->subDirs.push_back(d);
 59         dirNum++;
 60     }
 61     void addFile(string name,int size,int cluster) {
 62         this->subFiles.push_back(File(name,size,cluster));
 63         fileNum++;
 64     }
 65 
 66     Directory() {
 67         dirName = "";
 68     }
 69     Directory(string n) {
 70         this->dirName = n;
 71     }
 72 
 73     //判断有没有son这个儿子
 74     int hasSon(string son) {
 75         for (int i = 0; i < dirNum; i++) {
 76             if (son.compare(subDirs[i].dirName) == 0) {
 77                 return 1;
 78             }
 79         }
 80         return 0;
 81     }
 82     //判断有没有这个file, 并返回cluster
 83     int hasFile(string file) {
 84         for (int i = 0; i < fileNum; i++) {
 85             if (file.compare(subFiles[i].filename) == 0) {
 86                 return subFiles[i].firstCluster; //存在文件,返回cluster
 87             }
 88         }
 89         return -1; //不存在文件,返回-1
 90     }
 91 
 92 };
 93 
 94 
 95 vector<string> path; //当前已经遍历的目录
 96 
 97 string getPath() {
 98     string res = "/";
 99     for (int i = 0; i < path.size(); i++) {
100         res += (path[i] + "/");
101     }
102     return res ;
103 }
104 
105 void ls_display(Directory d) {
106     if (d.dirName.length()>0) path.push_back(d.dirName); //if not root dir
107     print(getPath()+":\n",0);
108     if(d.dirName.length()>0) print(".  ..  ",1);
109     for (int i = 0; i < d.dirNum; i++) {
110         print(d.subDirs[i].dirName+"  ",1);
111     }
112     for (int i = 0; i < d.fileNum; i++) {
113         print(d.subFiles[i].filename+"  ",0);
114     }
115     print("\n",0);
116     for (int i = 0; i < d.dirNum; i++) {
117         ls_display(d.subDirs[i]);
118     }
119     if (d.dirName.length() > 0)
120     {
121         path.pop_back();
122     }
123 }
124 
125 void ls_l_display(Directory d) {
126     if (d.dirName.length() > 0) path.push_back(d.dirName); //if not root dir
127     print(getPath() +" " + to_string(d.dirNum) + " " + to_string(d.fileNum)+":\n",0);
128     if (d.dirName.length() > 0) print( ".\n..\n",1);
129     for (int i = 0; i < d.dirNum; i++) {
130         print(d.subDirs[i].dirName,1);
131         print("  " + to_string(d.subDirs[i].dirNum) + " " + to_string(d.subDirs[i].fileNum)+"\n",0);
132     }
133     for (int i = 0; i < d.fileNum; i++) {
134         print(d.subFiles[i].filename +"  " + to_string(d.subFiles[i].size)+"\n",0);
135     }
136     print("\n",0);
137     for (int i = 0; i < d.dirNum; i++) {
138         ls_l_display(d.subDirs[i]);
139     }
140     if (d.dirName.length() > 0) path.pop_back();
141 }
142 
143 
144 /*
145     get dir node by dir name (note: name is unique)
146 */
147 Directory getDirectory(Directory beginDir,string dirName) {
148     if (beginDir.dirName.compare(dirName) == 0) {
149         return beginDir; //get it, the current dir is what i want
150     }
151     //fond in the subdir:
152     for (int i = 0; i < beginDir.dirNum; i++) {
153         Directory temp_dir= getDirectory(beginDir.subDirs[i], dirName);
154         if (temp_dir.dirName.length() != 0)return temp_dir;
155     }
156     return Directory();
157 }
158 
159 
160 
161 
162 //Part2: BPB and FAT operations
163 
164 typedef unsigned char u8;    //1B
165 typedef unsigned short u16;    //2B
166 typedef unsigned int u32;    //4B
167 
168 int  BytsPerSec;    //Bytes of every sector
169 int  SecPerClus;    //sectors of a cluster
170 int  RsvdSecCnt;    //Boot记录占用的扇区数
171 int  NumFATs;    //FAT tables Num
172 int  RootEntCnt;    //max files Num of root directory
173 int  FATSz;    //num of FAT sectors 
174 
175 #pragma pack (1) /*指定按1字节对齐*/
176 
177 //offset is 11 bytes
178 struct BPB {
179     u16  BPB_BytsPerSec;    //每扇区字节数
180     u8   BPB_SecPerClus;    //每簇扇区数
181     u16  BPB_RsvdSecCnt;    //Boot记录占用的扇区数
182     u8   BPB_NumFATs;    //FAT表个数
183     u16  BPB_RootEntCnt;    //根目录最大文件数
184     u16  BPB_TotSec16;
185     u8   BPB_Media;
186     u16  BPB_FATSz16;    //FAT扇区数
187     u16  BPB_SecPerTrk;
188     u16  BPB_NumHeads;
189     u32  BPB_HiddSec;
190     u32  BPB_TotSec32;    //如果BPB_FATSz16为0,该值为FAT扇区数
191 };
192 //BPB over,length is 25 bytes
193 
194 //root directory entry
195 struct RootEntry {
196     char DIR_Name[11];
197     u8   DIR_Attr;        //file attr
198     char reserved[10];
199     u16  DIR_WrtTime;
200     u16  DIR_WrtDate;
201     u16  DIR_FstClus;    //start cluster No
202     u32  DIR_FileSize;
203 };
204 //根目录条目结束,32字节
205 #pragma pack () /*取消指定对齐,恢复缺省对齐*/
206 
207 struct subEntry {
208     char DIR_Name[11];
209     u8  DIR_Attr;
210     char reserved[10];
211     u16  DIR_WrTime;
212     u16  DIR_WrDate;
213     u16  DIR_FstClus;
214     u32  DIR_FileSize;
215 };
216 
217 #pragma pack () /*取消指定对齐,恢复缺省对齐*/
218 
219 
220 void fillBPB(struct BPB* bpb_ptr);    //载入BPB
221 void printFiles(struct RootEntry* rootEntry_ptr, Directory* rootnode);    //打印文件名,这个函数在打印目录时会调用下面的printChildren
222 void printChildren(char * directory, int startClus,Directory * d);    //打印目录及目录下子文件名
223 int  getFATValue(int num);    //读取num号FAT项所在的两个字节,并从这两个连续字节中取出FAT项的值,
224 void printFileContent(int startClus);
225 int getFATValue(int num);
226 
227 Directory root;
228 FILE* fat12;  //global variable
229 
230 void init() {
231     struct BPB bpb;
232     struct BPB* bpb_ptr = &bpb;
233 
234     //载入BPB
235     fillBPB(bpb_ptr);
236 
237     //init all global variables
238     BytsPerSec = bpb_ptr->BPB_BytsPerSec;
239     SecPerClus = bpb_ptr->BPB_SecPerClus;
240     RsvdSecCnt = bpb_ptr->BPB_RsvdSecCnt;
241     NumFATs = bpb_ptr->BPB_NumFATs;
242     RootEntCnt = bpb_ptr->BPB_RootEntCnt;
243     if (bpb_ptr->BPB_FATSz16 != 0) {
244         FATSz = bpb_ptr->BPB_FATSz16;
245     }
246     else {
247         FATSz = bpb_ptr->BPB_TotSec32;
248     }
249 
250     struct RootEntry rootEntry;
251     struct RootEntry* rootEntry_ptr = &rootEntry;
252 
253     //print in cursion
254     printFiles(rootEntry_ptr,&root);
255 }
256 //erase the spaces in the biginning and end
257 string& trim(std::string &s)
258 {
259     if (s.empty()) return s;
260     s.erase(0, s.find_first_not_of(" "));
261     s.erase(s.find_last_not_of(" ") + 1);
262     return s;
263 }
264 
265 string ls_l_resolve(string command) {
266     const char * cmd1 = command.c_str();
267     int len = command.length();
268 
269     //处理 -lll这种多个l的情况
270     int _l_beginIndex = 0;
271     for (int i = 0; i < len-1; i++) {
272         if (cmd1[i] == '-'&&cmd1[i + 1] == 'l') {
273             _l_beginIndex = i + 1;
274             break;
275         }
276     }
277     int l_endIndex = _l_beginIndex;
278     for (int i = _l_beginIndex + 1; i < len; i++) {
279         if (cmd1[i] != 'l') {
280             l_endIndex = i;
281             break;
282         }
283     }
284     if (_l_beginIndex != l_endIndex) {
285         command = command.substr(0, _l_beginIndex+1) + command.substr(l_endIndex,len-l_endIndex);
286     }
287     //cout << "comm:" << command << endl;
288     const char * cmd = command.c_str();
289     len = command.length();
290 
291     int beginIndex = 0, endIndex = 0;
292     int hasBegun = 0; //是否已经进入目录的 beginIndex
293 
294     //form1:ls path -l
295     if (cmd[len - 1] == 'l'&&cmd[len - 2] == '-') {
296         for (int i = 3; i < len; i++) {
297             if (cmd[i] != ' '&&!hasBegun) {
298                 beginIndex = i;
299                 hasBegun = 1;
300                 //break;
301             }
302             if (hasBegun && (cmd[i] == ' ' || cmd[i] == '-')) {
303                 endIndex = i;
304                 break;
305             }
306         }
307     }
308     else {
309         //form2:ls -l path
310         for (int i = 3; i < len; i++) {
311             if (cmd[i] == '-'&&cmd[i + 1] == 'l') {
312                 beginIndex = i + 1;
313                 break;
314             }
315         }
316         for (int i = beginIndex+1; i < len; i++) {
317             if (cmd[i] != ' ') {
318                 beginIndex = i;
319                 break;
320             }
321         }
322         endIndex = len;
323     }
324     string res = command.substr(beginIndex, endIndex - beginIndex);
325     return res;
326 }
327 //to upper
328 string upper(string s) {
329     string res;
330     const char* c = s.c_str();
331     for (int i = 0; i < s.length(); i++) {
332         if (c[i] > 96&&c[i]<127)res += (c[i] - 32);
333         else res += c[i];
334     }
335     return res;
336 }
337 //tranform path like '/a/b/c', return a vector
338 vector<string> getPathVector(string path) {
339     vector<string> pathVec;
340     const char* pathChars = path.c_str();
341     int len = path.length();
342     int beginIndex = 0;
343     if (pathChars[0] == '/')beginIndex++;
344     char temp[20];//temp char arr
345     for (int i = beginIndex; i < len; i++) {
346         if (pathChars[i] == '/'||i==len-1) {
347             pathVec.push_back(path.substr(beginIndex,(i==len-1)?len:i-beginIndex));
348             beginIndex = i + 1;
349         }
350     }
351     return pathVec;
352 }
353 
354 //得到路径中的目录
355 Directory locateDirectory(string path) {
356     path = upper(path);
357     vector<string> pathVector = getPathVector(path);
358     vector <Directory> dirArr;
359 
360     for (int i = 0; i < pathVector.size(); i++) {
361         dirArr.push_back(getDirectory(root, pathVector[i]));
362     }
363     
364     Directory res = dirArr[dirArr.size() - 1];
365     int isOK = 1;
366     if(dirArr.size()==1){
367         if(dirArr[0].dirName.length()==0)isOK=0;
368     }
369     else{
370         for (int i = 0; i < pathVector.size() - 1; i++) {
371             if (!dirArr[i].hasSon(dirArr[i + 1].dirName)) {
372                 isOK = 0;
373                 break;
374             }
375         }
376     }
377     if (!isOK) res.dirNum = -1; //如果路径不正确,将返回目录节点的dirName置-1
378     return res;
379 }
380 
381 void Main() {
382     string inp;
383     while (1)
384     {
385         print(">",0);
386         getline(cin, inp);
387         inp = trim(inp);
388 
389         const char* c_inp = inp.c_str();
390         
391         int has_ = 0;
392         for(int i =0;i<inp.length();i++){
393             if(c_inp[i]=='-'){
394                 has_ = 1;
395                 break;
396             }
397         }
398         
399         if (inp.compare("exit") == 0) {
400             print( "Bye!\n",0);
401             break;
402         }
403         if (inp.length() >= 2 && c_inp[0] == 'l'&&c_inp[1] == 's') {
404             if (!inp.compare("ls")) {
405                 ls_display(root);
406             }
407             else if(!inp.substr(0,2).compare("ls")&&!has_){
408                 string path = inp.substr(2,inp.length()-2);
409                 path = trim(path);
410                 Directory dir = locateDirectory(path);
411                 ls_display(dir);
412             }
413             else if(!inp.compare("ls -l")) {
414                 ls_l_display(root);
415             }
416             else if(!inp.substr(0,5).compare("ls -L")) {
417                 print("your command is invalid!\n",0);
418             }
419             else {
420                 string path = ls_l_resolve(inp);  
421                 //cout << "path: " << path << endl;
422                 
423                 if (path.length() == 0) {
424                     print("The path is invalid! Try again!\n",0);
425                 }
426                 else {
427                     Directory dir = locateDirectory(path);
428                     if (dir.dirNum==-1) {
429                         print("The path is invalid! Try again!\n",0);
430                     }
431                     else {
432                         ls_l_display(dir);
433                     }
434                 }
435             }
436         }
437         else if (!inp.substr(0,3).compare("cat")) {
438             int i;
439             for (i = 3; i < inp.length(); i++) {
440                 if (c_inp[i] != ' ')break;  //取出cat后面的space
441             }
442             //取出文件和目录:
443             int endIndex = inp.length() - 1;
444             for (int i = endIndex; i >= 3; i--) {
445                 if (c_inp[i] == '/') {
446                     endIndex = i;
447                     break;
448                 }
449             }
450 
451             string path = inp.substr(i, endIndex - i);
452             string fileName = inp.substr(endIndex + 1, inp.length() - endIndex - 1);
453 
454             if (endIndex == inp.length() - 1) {
455                 path = "";
456                 fileName = inp.substr(i, inp.length()-i);
457             }
458             //cout << "path: " << path << " file: " << fileName << endl;
459             Directory dir;
460             if (path.length() == 0) { //path is empty, so it's root entry
461                 dir = root;
462             }
463             else {
464                 dir = locateDirectory(path);
465             }
466             if (dir.dirNum == -1) {
467                 print("The path is invalid!\n",0);
468             }
469             else {
470                 int cluster = dir.hasFile(upper(fileName));
471                 if (cluster==-1) {
472                     print("The file is not exist!\n",0);
473                 }
474                 else {
475                     if (cluster >= 2) 
476                         printFileContent(cluster);
477                 }
478 
479             }
480         }
481         else if(inp.length()>0){
482             string s = "Wrong Command! Try Again!\n";
483             print(s,0);
484         }
485     }
486 }
487 
488 
489 void fillBPB( struct BPB* bpb_ptr) {
490     int check;
491     //BPB从偏移11个字节处开始
492     check = fseek(fat12, 11, SEEK_SET);
493     if (check == -1)
494         print("fseek in fillBPB failed!\n",0);
495 
496     //BPB长度为25字节
497     check = fread(bpb_ptr, 1, 25, fat12);
498     if (check != 25)
499         print("fread in fillBPB failed!\n",0);
500 }
501 
502 
503 void printFiles(struct RootEntry* rootEntry_ptr, Directory* root) {
504     int base = (RsvdSecCnt + NumFATs * FATSz) * BytsPerSec;    //根目录首字节的偏移数
505     int check;
506     char realName[12];    //暂存将空格替换成点后的文件名
507 
508     //依次处理根目录中的各个条目
509     int i;
510     for (i = 0; i < RootEntCnt; i++) {
511 
512         check = fseek(fat12, base, SEEK_SET);
513         if (check == -1)
514             print("fseek in printFiles failed!\n",0);
515 
516         check = fread(rootEntry_ptr, 1, 32, fat12);
517         if (check != 32)
518             print("fread in printFiles failed!\n",0);
519         base += 32;
520         if (rootEntry_ptr->DIR_Name[0] == '\0') continue;    //empty entry
521 
522         //filliter ilvalid
523         int j;
524         int boolean = 0;
525         for (j = 0; j < 11; j++) {
526             if (!(((rootEntry_ptr->DIR_Name[j] >= 48) && (rootEntry_ptr->DIR_Name[j] <= 57)) ||
527                 ((rootEntry_ptr->DIR_Name[j] >= 65) && (rootEntry_ptr->DIR_Name[j] <= 90)) ||
528                 ((rootEntry_ptr->DIR_Name[j] >= 97) && (rootEntry_ptr->DIR_Name[j] <= 122)) ||
529                 (rootEntry_ptr->DIR_Name[j] == ' '))) {
530                 boolean = 1;    //invalid char
531                 break;
532             }
533         }
534         if (boolean == 1) continue;    //not object
535 
536         int k;
537         if ((rootEntry_ptr->DIR_Attr & 0x10) == 0) {
538             //it's a file 
539             int tempLong = -1;
540             for (k = 0; k < 11; k++) {
541                 if (rootEntry_ptr->DIR_Name[k] != ' ') {
542                     tempLong++;
543                     realName[tempLong] = rootEntry_ptr->DIR_Name[k];
544                 }
545                 else {
546                     tempLong++;
547                     realName[tempLong] = '.';
548                     while (rootEntry_ptr->DIR_Name[k] == ' ') k++;
549                     k--;
550                 }
551             }
552             tempLong++;
553             realName[tempLong] = '\0';    //filename is realName
554 
555             root->addFile(realName,rootEntry_ptr->DIR_FileSize,rootEntry_ptr->DIR_FstClus);
556             //output fileName:
557             //printf("FileName: %s\n", realName);
558         }
559         else {
560             //it's a dir
561             int tempLong = -1;
562             for (k = 0; k < 11; k++) {
563                 if (rootEntry_ptr->DIR_Name[k] != ' ') {
564                     tempLong++;
565                     realName[tempLong] = rootEntry_ptr->DIR_Name[k];
566                 }
567                 else {
568                     tempLong++;
569                     realName[tempLong] = '\0';
570                     break;
571                 }
572             }    //dir name is realName
573 
574             Directory d = Directory(realName);
575             root->addDir(d);
576 
577             //priint recurisively
578             printChildren(realName, rootEntry_ptr->DIR_FstClus, &root->subDirs[root->dirNum-1]);
579         }
580     }
581 }
582 
583 
584 void printChildren(char * directory, int startClus,Directory* d) {
585     //offset of No.2 cluster(the first cluster)
586     int dataBase = BytsPerSec * (RsvdSecCnt + FATSz * NumFATs + (RootEntCnt * 32 + BytsPerSec - 1) / BytsPerSec);
587     char fullName[240];    //file /dir fullname
588     int strLength = strlen(directory);
589     strcpy(fullName, directory);
590     fullName[strLength] = '/';
591     strLength++;
592     fullName[strLength] = '\0';
593     char* fileName = &fullName[strLength];
594 
595     int currentClus = startClus;
596     int value = 0;
597     int ifOnlyDirectory = 0;
598 
599     while (value < 0xFF8) { //value <FF8H
600         value = getFATValue(currentClus);
601         if (value < 0) {
602             break;
603         }
604         if (value == 0xFF7) {
605             print("Bad cluster,failed!\n",0);
606             break;
607         }
608 
609         char* str = (char*)malloc(SecPerClus*BytsPerSec);    //暂存从簇中读出的数据
610         char* content = str;
611 
612         int startByte = dataBase + (currentClus - 2)*SecPerClus*BytsPerSec;
613         int check;
614         check = fseek(fat12, startByte, SEEK_SET);
615         if (check == -1)
616             print("fseek in printChildren failed!\n",0);
617 
618         check = fread(content, 1, SecPerClus*BytsPerSec, fat12);
619         if (check != SecPerClus * BytsPerSec)
620             print("fread in printChildren failed!\n",0);
621 
622         //solve date of content,the regular entry structure is as same as root dir entry.
623         int count = SecPerClus * BytsPerSec;    //bytes of a cluster
624         int loop = 0;
625         while (loop < count) {
626             int i;
627             char tempName[120];    //暂存替换空格为点后的文件名
628             if (content[loop] == '\0') {
629                 loop += 32;
630                 continue;
631             }    //empty entry
632 
633                 //filiter the invaild things
634             int j;
635             int boolean = 0;
636             for (j = loop; j < loop + 11; j++) {
637                 if (!(((content[j] >= 48) && (content[j] <= 57)) ||
638                     ((content[j] >= 65) && (content[j] <= 90)) ||
639                     ((content[j] >= 97) && (content[j] <= 122)) ||
640                     (content[j] == ' '))) {
641                     boolean = 1;    //invaild char
642                     break;
643                 }
644             }
645             if (boolean == 1) {
646                 loop += 32;
647                 continue;
648             }    //not object file
649 
650             if ((content[loop + 11] & 0x10) == 0) {
651                 //File :
652                 int k;
653                 int tempLong = -1;
654                 for (k = 0; k < 11; k++) {
655                     if (content[loop + k] != ' ') {
656                         tempLong++;
657                         tempName[tempLong] = content[loop + k];
658                     }
659                     else {
660                         tempLong++;
661                         tempName[tempLong] = '.';
662                         while (content[loop + k] == ' ') k++;
663                         k--;
664                     }
665                 }
666                 tempLong++;
667                 tempName[tempLong] = '\0';    
668 
669                 int a = content[loop+28],
670                     b = content[loop + 29],
671                     c = content[loop + 30],
672                     d1 = content[loop + 31];
673                 a = a >= 0 ? a : 256 + a;//处理负数
674                 b = b >= 0 ? b: 256 + b;
675                 c = c >= 0 ? c : 256 + c;
676                 d1 = d1 >= 0 ? d1 : 256 + d1;
677 
678                 int size = a + 256*b + 256*256*c + 256*256*256*d1;
679 
680                 int x = content[loop + 26];
681                 int y = content[loop + 27];
682                 //cout << "cluster of : " << fullName<<"/"<<tempName<<" :" <<y * 256 + x << endl;
683                 d->addFile(tempName,size, y * 256 + x);
684                 strcpy(fileName, tempName);
685                 //printf("%s\n", fullName);
686                 ifOnlyDirectory = 1;
687             }
688             else {
689                 //dir
690                 int k;
691                 int tempLong = -1;
692 
693                 for (k = 0; k < 11; k++) {
694                     if (content[loop + k] != ' ') {
695                         tempLong++;
696                         tempName[tempLong] = content[loop + k];
697                     }
698                     else {
699                         while (content[loop + k] == ' ') k++;
700                         k--;
701                     }
702                 }
703                 tempLong++;
704                 tempName[tempLong] = '\0';
705                 strcpy(fileName, tempName);
706                 ifOnlyDirectory == 1;
707 
708                 Directory dir = Directory(tempName);
709                 d->addDir(dir);
710 
711                 int a = content[loop + 26];
712                 int b = content[loop + 27];
713                 printChildren(fullName, b*256+a, &d->subDirs[d->dirNum-1]);
714             }
715             loop += 32;
716         }
717         free(str);
718         currentClus = value;
719     };
720     //if (ifOnlyDirectory == 0)
721     //    printf("%s\n", fullName);    //空目录的情况下,输出目录
722 }
723 
724 //输出文件内容:
725 void printFileContent(int startClus) {
726     int dataBase = BytsPerSec * (RsvdSecCnt + FATSz * NumFATs + (RootEntCnt * 32 + BytsPerSec - 1) / BytsPerSec);
727     int check;
728     int curclus = startClus;
729     int value = 0;
730     while (value < 0xFF8) {//4088
731         value = getFATValue(curclus);
732         if (value < 0) {
733             break;
734         }
735         if (value == 0xFF7) {
736             print( "bad cluster\n",0);
737         }
738         char temp[513];
739         int startByte = dataBase + 512 * (curclus - 2);
740         check = fseek(fat12, startByte, SEEK_SET);
741         if (check == -1)print( "Failed!\n",0);
742         check = fread(temp, 1, 512, fat12);
743         temp[512] = '\0';
744         print(temp,0);
745         print("\n",0);
746         curclus = value;
747     }
748 }
749 
750 
751 int getFATValue(int num) {
752     int fatBase = RsvdSecCnt * BytsPerSec;
753     int fatPos = fatBase + num * 3 / 2;
754     int type = 0;
755     if (num % 2 == 0) {
756         type = 0; //even
757     }
758     else {
759         type = 1; //odd
760     }
761     u16 bytes;
762     u16* bytes_ptr = &bytes;
763     int check;
764     check = fseek(fat12, fatPos, SEEK_SET);
765     if (check == -1) {
766         print("fseek in getFATValue failed!\n",0);
767         return -1;
768     }
769     check = fread(bytes_ptr, 1, 2, fat12);
770     if (check != 2) {
771         print("fread in getFATValue failed!\n",0);
772         return -1;
773     }
774     //u16为short,结合存储的小端顺序和FAT项结构可以得到
775     //type为0的话,取byte2的低4位和byte1构成的值,type为1的话,取byte2和byte1的高4位构成的值
776     if (type == 0) {
777         bytes = bytes << 4;
778         bytes = bytes >> 4;
779     }
780     else {
781         bytes = bytes >> 4;
782     }
783     return bytes;
784 }
785 
786 
787 
788 // Main, entrance of this program
789 int main() {
790     fat12 = fopen(IMG_PATH, "rb");    //open the fat12 image
791     init(); //init, build the file tree
792     Main(); //command solve and execute
793     fclose(fat12); //clost the file stream in the last。
794     return 0;
795 }

 

NASM CODE:

my_print.asm

 1 global myPrint
 2 ;void myPrint(char *,int len,int color);
 3 ;color: 0-default, 1-red
 4 ;EdwinXu
 5 section .data
 6     color_default:  db  1Bh, '[37;0m', 0 
 7     .length            equ $ - color_default
 8     color_red:      db  1Bh, '[31;1m', 0
 9     .length            equ $ - color_red  
10 
11 section .text
12 
13 myPrint:
14     mov eax, [esp+12]
15     cmp eax, 0
16     je default_color
17     
18 ;set red 
19     mov eax, 4
20     mov ebx, 1
21     mov ecx, color_red
22     mov edx, color_red.length
23     int 80h
24     jmp color_end
25 ;set default color:
26 default_color:
27     mov eax, 4
28     mov ebx, 1
29     mov ecx, color_default
30     mov edx, color_default.length
31     int 80h
32 
33 ;print the str
34 color_end:
35     mov eax, 4
36     mov ebx, 1
37     mov ecx, [esp+4] ;str
38     mov edx, [esp+8] ;len
39     int 80h
40 ;recover the color
41     mov eax, 4
42     mov ebx, 1
43     mov ecx, color_default
44     mov edx, color_default.length
45     int 80h
46     
47     ret

 

Makefile:

all:

ALL:
    nasm -f elf32 my_print.asm
    g++ -m32 my_print.o Main.cpp -o main
    ./main

 

 

 

posted @ 2019-11-13 22:55  Edwin_Xu  阅读(392)  评论(0编辑  收藏  举报