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