Форум Программирование Кому интересно разобраться в проге имитирующей FAT на С++ (прога есть!!) |
Страницы: «1» «2» | |||||||
|
Пишу на C++ имитацию FAT 16/32 код уже в общем то рабочий есть, проблемы в том что : 1)никак не могу засунуть в cd lc 2)при компиляции в VS в конце корневой папки выдает неясную ошибку в виде "Эээээ" в коде этого нет 3)Криво открывает вложенные папки, почему не могу найти. переделал с потоков на нормаль, но все равно ничего не изменилось,может если кому интересно - гляньте что к чему Main #pragma pack(1) #include <iostream> #include <fstream> #include "Header.h" /*--------------------------------------------------------------------------------------------------*/ DateTime UnpackDateTime(word date, word time); void showDirectoryContent(char ** possibleDestNameList, char** fileNameList, int depth); void DrowLine(int len); void show_Console(); void getDirContent(byte* Dir, char ** possibleDestNameList, dword * possibleDestPtrList, char ** fileNameList, dword* filePtrList, char sz); void clearAll(char ** possibleDestNameList, char ** fileNameList,dword * possibleDestPtrList, dword * filePtrList); void decode(char * str); dword getNext(byte* fat , dword clusterNum); void lower(std::string& s); bool DirectoryEntry::IsLFN() const { return !IsDeleted() && !IsAtEnd() && (attribute==0x0F && reserved0 == 0x0 && Node_low == 0x0); } bool DirectoryEntry::IsDirectory() const { return !IsDeleted() && !IsAtEnd() && (attribute & Directory); } bool DirectoryEntry::IsAtEnd() const { return FileName[0]==0; } bool DirectoryEntry::IsDeleted() const { return (unsigned char)FileName[0]==0xE5; } DateTime DirectoryEntry::GetCreationDate() const { return UnpackDateTime(CreationDate, CreationTime); } DateTime DirectoryEntry::GetLastAccessDate() const { return UnpackDateTime(AccessDate, 0); } DateTime DirectoryEntry::GetLastModificationDate() const { return UnpackDateTime(UpdateDate, UpdateTime); } /*--------------------------------------------------------------------------------------------------*/ int main() { byte* buffer = 0; byte* buffer2 = 0; byte* buffer3 = 0; byte* fat = 0; char dest[]="\\\\.\\F:"; char * possibleDestNameList[500] = {0}; char * fileNameList[500] = {0}; dword possibleDestPtrList[500] = {0}; dword filePtrList[1000] ={0}; dword upDR[100] = {0}; std::string command, moveTo, listingAtr, copy; char a = 0; char Letter ='F'; int depth = 0; int k = 0; int iter1 = 0; int num=0; int additionalshift = 0; dword bytesReturned = 0, fbufferSize = 0, fbufferSize2 = 0, sbufferSize = 0, max = 0, SC = 0, SPF = 0, TS = 0, RDO = 0, cDir = 0; long double forCeil = 0, SSA = 0, forFloor = 0; BootSector bs = {0}; ExtBootSector32 ebs32 = {0}; ExtBootSector ebs = {0}; /*---------------------------------------------------------------------------------------------*/ std::cout<<"Enter the device letter:"; std::cin >> dest[4]; /* system("cls"); if ((a!='q') && (a >= 'A') && (a <= 'Z')) Letter = a; //sprintf(dest, 7, "\\\\.\\%c:", Letter ); sprintf(dest, "\\\\.\\%c:", Letter ); //sprintf_s(RootDirName, 5, "%c:\\\\\0", Letter); sprintf(RootDirName, "%c:\\\\", Letter); */ FILE * Disk = fopen(dest, "rb"); if(Disk == NULL) { std::cout << "Unable to open disk" << std::endl; return 1; } //std::ifstream Disk (dest, std::ios::in | std::ios::binary); buffer = (byte *)malloc(100); fread( (char *)buffer, 100, 1, Disk); //Disk.read((char *)buffer, 100); memcpy(&bs, buffer, sizeof(bs)); fbufferSize = bs.bpb.bpbBytesPerSector*bs.bpb.bpbSectorsPerTrack; buffer = (byte *)realloc(buffer, fbufferSize); _fseeki64( Disk, 0, SEEK_SET ); //Disk.seekg(0, std::ios::beg); fread( (char *)buffer, fbufferSize, 1, Disk); //Disk.read((char *)buffer, fbufferSize); TS = bs.bpb.bpbTotalSectors; if (TS == 0) TS = bs.bpb.bpbTotalSectorsBig; forCeil = (32*bs.bpb.bpbRootEntries)/bs.bpb.bpbBytesPerSector; SSA = bs.bpb.bpbReservedSectors+(bs.bpb.bpbNumberOfFATs*bs.bpb.bpbSectorsPerFAT)+/*ceil(forCeil)*/int(forCeil); SC = bs.bpb.bpbSectorsPerCluster; forFloor = (TS-SSA)/SC; max = 1 + dword(forFloor); if(max < 4085) { fat_type = 12; } else { if(max < 65525) { fat_type = 16; } else { fat_type = 32; } } std::cout << int (bs.bpb.bpbNumberOfFATs) << '\n'; /*----------------------------------------------------------------------------------------------*/ if (fat_type==32) memcpy(&ebs32, buffer + sizeof(bs), sizeof(ebs32)); else memcpy(&ebs, buffer + sizeof(bs), sizeof(ebs)); if (fat_type == 12) { std::cout<<"Fat12 is not supported."<<std::endl; system("pause"); return -4; } if(fat_type == 32) { SPF = ebs32.bpb32SectorsPerFAT; sizeFat = 4; } else { SPF = bs.bpb.bpbSectorsPerFAT; sizeFat = 2; } free(buffer); RDO = bs.bpb.bpbReservedSectors * bs.bpb.bpbBytesPerSector + SPF * bs.bpb.bpbBytesPerSector * bs.bpb.bpbNumberOfFATs; fat = (byte *)malloc(SPF*bs.bpb.bpbBytesPerSector); _fseeki64( Disk, bs.bpb.bpbReservedSectors * bs.bpb.bpbBytesPerSector, SEEK_SET ); //Disk.seekg(bs.bpb.bpbReservedSectors * bs.bpb.bpbBytesPerSector, std::ios::beg); fread( (char *)fat, SPF*bs.bpb.bpbBytesPerSector, 1, Disk); //Disk.read((char *)fat, SPF*bs.bpb.bpbBytesPerSector); dword sizeofRead = bs.bpb.bpbBytesPerSector *bs.bpb.bpbSectorsPerCluster; dword sizeofFolderRead = sizeofRead; buffer2 = (byte *)malloc(sizeofRead); buffer3 = (byte *)malloc(sizeofRead); strncpy(currDir, RootDirName, strlen(RootDirName)+1); setlocale(LC_CTYPE, ""); dword clusterNum = 2; int FolderClusterCounter = 0; if(fat_type == 32) { while(clusterNum*sizeFat < SPF*bs.bpb.bpbBytesPerSector) { sizeofFolderRead = (FolderClusterCounter+1)*sizeofRead; buffer2 = (byte *)realloc(buffer2, sizeofFolderRead); _fseeki64( Disk, RDO + (clusterNum-2) * sizeofRead, SEEK_SET ); //Disk.seekg(RDO + (clusterNum-2) * sizeofRead, std::ios::beg); fread( (char *)buffer2+FolderClusterCounter*sizeofRead, sizeofRead, 1, Disk); //Disk.read((char *)buffer2+FolderClusterCounter*sizeofRead, sizeofRead); clusterNum = getNext(fat, clusterNum); FolderClusterCounter++; } } else { sizeofFolderRead = bs.bpb.bpbRootEntries*32; buffer2 = (byte *)realloc(buffer2, sizeofFolderRead); _fseeki64( Disk, RDO, SEEK_SET ); //Disk.seekg(RDO, std::ios::beg); fread( (char *)buffer2, sizeofFolderRead, 1, Disk); //Disk.read((char *)buffer2, sizeofFolderRead); } getDirContent(buffer2, possibleDestNameList, possibleDestPtrList, fileNameList, filePtrList, 0); show_Console(); while(true) { std::cin>>command; if(!command.compare("cls")) { system("cls"); show_Console(); } /*------------------------------------------------------------------------------------------*/ if(!command.compare("ls")) { char c = getchar(); std::cout<<(int)c<<std::endl; if (c==' '){ clearAll(possibleDestNameList, fileNameList, possibleDestPtrList, filePtrList); std::cin>>listingAtr; show_Console(); free(buffer2); buffer2 = 0; FolderClusterCounter = 0; clusterNum = cDir+2; while(clusterNum*sizeFat < SPF*bs.bpb.bpbBytesPerSector) { if(fat_type == 16&& depth ==0) sizeofFolderRead = bs.bpb.bpbRootEntries*sizeof(DirectoryEntry); else sizeofFolderRead = (FolderClusterCounter+1)*sizeofRead; buffer2 = (byte *)realloc(buffer2, sizeofFolderRead); if(fat_type == 32) _fseeki64( Disk, RDO + (clusterNum-2) * sizeofRead, SEEK_SET ); //Disk.seekg(RDO + (clusterNum-2) * sizeofRead, std::ios::beg); else if(depth!=0) _fseeki64( Disk, RDO + bs.bpb.bpbRootEntries*sizeof(DirectoryEntry) + (clusterNum-2) * sizeofRead, SEEK_SET ); //Disk.seekg(RDO + bs.bpb.bpbRootEntries*sizeof(DirectoryEntry) + (clusterNum-2) * sizeofRead, std::ios::beg); else _fseeki64( Disk, RDO, SEEK_SET ); //Disk.seekg(RDO , std::ios::beg); if(fat_type == 16 && depth ==0) { fread( (char *)buffer2, sizeofFolderRead, 1, Disk); //Disk.read((char *)buffer2, sizeofFolderRead); break; } else fread( (char *)buffer2+FolderClusterCounter*sizeofRead, sizeofRead, 1, Disk); //Disk.read((char *)buffer2+FolderClusterCounter*sizeofRead, sizeofRead); clusterNum = getNext(fat, clusterNum); FolderClusterCounter++; } if(!listingAtr.compare("-s")) { getDirContent(buffer2+additionalshift, possibleDestNameList, possibleDestPtrList, fileNameList, filePtrList, 1); showDirectoryContent(possibleDestNameList, fileNameList, depth); continue; } if(!listingAtr.compare("-ct")) { getDirContent(buffer2+additionalshift, possibleDestNameList, possibleDestPtrList, fileNameList, filePtrList, 2); showDirectoryContent(possibleDestNameList, fileNameList, depth); continue; } if(!listingAtr.compare("-mt")) { getDirContent(buffer2+additionalshift, possibleDestNameList, possibleDestPtrList, fileNameList, filePtrList, 3); showDirectoryContent(possibleDestNameList, fileNameList, depth); continue; } if(!listingAtr.compare("help")) { show_Console(); std::cout<<"\n\"ls\" shows files in the current directory.\n\"ls -s\" print size of files.\n\"ls -ct\" print creation time of files.\n\"ls -mt\" print last modification time of files.\n\n"; system("pause"); show_Console(); continue; } } clearAll(possibleDestNameList, fileNameList, possibleDestPtrList, filePtrList); show_Console(); free(buffer2); buffer2 = 0; FolderClusterCounter = 0; clusterNum = cDir+2; while(clusterNum*sizeFat < SPF*bs.bpb.bpbBytesPerSector) { if(fat_type == 16&& depth ==0) sizeofFolderRead = bs.bpb.bpbRootEntries*sizeof(DirectoryEntry); else sizeofFolderRead = (FolderClusterCounter+1)*sizeofRead; buffer2 = (byte *)realloc(buffer2, sizeofFolderRead); if(fat_type == 32) _fseeki64( Disk, RDO + (clusterNum-2) * sizeofRead, SEEK_SET ); //Disk.seekg(RDO + (clusterNum-2) * sizeofRead, std::ios::beg); else if(depth!=0) _fseeki64( Disk, RDO + bs.bpb.bpbRootEntries*sizeof(DirectoryEntry) + (clusterNum-2) * sizeofRead, SEEK_SET ); //Disk.seekg(RDO + bs.bpb.bpbRootEntries*sizeof(DirectoryEntry) + (clusterNum-2) * sizeofRead, std::ios::beg); else _fseeki64( Disk, RDO, SEEK_SET ); //Disk.seekg(RDO , std::ios::beg); if(fat_type == 16 && depth ==0) { fread( (char *)buffer2,sizeofFolderRead, 1, Disk); //Disk.read((char *)buffer2, sizeofFolderRead); break; } else fread( (char *)buffer2+FolderClusterCounter*sizeofRead, sizeofRead, 1, Disk); //Disk.read((char *)buffer2+FolderClusterCounter*sizeofRead, sizeofRead); clusterNum = getNext(fat, clusterNum); FolderClusterCounter++; } getDirContent(buffer2+additionalshift, possibleDestNameList, possibleDestPtrList, fileNameList, filePtrList, 0); showDirectoryContent(possibleDestNameList, fileNameList, depth); } /*------------------------------------------------------------------------------------------*/ if(!command.compare("q")) break; /*------------------------------------------------------------------------------------------*/ if(!command.compare("cd")) { char c = getchar(); getline(std::cin, moveTo, '\n'); setlocale(LC_CTYPE, ""); decode(const_cast<char *>(moveTo.c_str())); lower(moveTo); if(!moveTo.compare("help")) { show_Console(); std::cout<<"\n\"cd \\\" will move you to root directory.\n\"cd ..\" will move you up one directory.\n\"cd $subfolder$\" will move you in a subdirectory called $subfolder$.\n\n"; system("pause"); show_Console(); } /*--------------------------------------------------------------------------------------*/ if(!moveTo.compare("\\")) { for(int i = depth; i>0; i--) { upDR[i]=0; } additionalshift=0; depth = 0; strncpy(currDir, RootDirName, strlen(RootDirName) +1); cDir = 0; free(buffer2); buffer2 = 0; FolderClusterCounter = 0; clusterNum = cDir+2; if(fat_type == 32) { while(clusterNum*sizeFat < SPF*bs.bpb.bpbBytesPerSector) { sizeofFolderRead = (FolderClusterCounter+1)*sizeofRead; buffer2 = (byte *)realloc(buffer2, sizeofFolderRead); _fseeki64( Disk, RDO + (clusterNum-2) * sizeofRead, SEEK_SET ); //Disk.seekg(RDO + (clusterNum-2) * sizeofRead, std::ios::beg); fread( (char *)buffer2+FolderClusterCounter*sizeofRead, sizeofRead, 1, Disk); //Disk.read((char *)buffer2+FolderClusterCounter*sizeofRead, sizeofRead); clusterNum = getNext(fat, clusterNum); FolderClusterCounter++; } } else { sizeofFolderRead = bs.bpb.bpbRootEntries*32; buffer2 = (byte *)realloc(buffer2, sizeofFolderRead); _fseeki64( Disk, RDO, SEEK_SET ); //Disk.seekg(RDO, std::ios::beg); fread( (char *)buffer2, sizeofFolderRead, 1, Disk); //Disk.read((char *)buffer2, sizeofFolderRead); } upDR[depth] = 0; clearAll(possibleDestNameList, fileNameList, possibleDestPtrList, filePtrList); getDirContent(buffer2, possibleDestNameList, possibleDestPtrList, fileNameList, filePtrList, 0); show_Console(); } int k = 0; while(possibleDestNameList[k]){ std::string s (possibleDestNameList[k]); lower(s); if(!moveTo.compare(s)) { depth++; upDR[depth-1] = cDir; strncat(currDir, possibleDestNameList[k], 400); strncat(currDir, "\\", 400); cDir = possibleDestPtrList[k]; additionalshift = 2*sizeof(DirectoryEntry); free(buffer2); buffer2 = 0; FolderClusterCounter = 0; clusterNum = cDir+2; while(clusterNum*sizeFat < SPF*bs.bpb.bpbBytesPerSector) { if(fat_type == 16&& depth ==0) sizeofFolderRead = bs.bpb.bpbRootEntries*sizeof(DirectoryEntry); else sizeofFolderRead = (FolderClusterCounter+1)*sizeofRead; buffer2 = (byte *)realloc(buffer2, sizeofFolderRead); if(fat_type == 32) _fseeki64( Disk, RDO + (clusterNum-2) * sizeofRead, SEEK_SET ); //Disk.seekg(RDO + (clusterNum-2) * sizeofRead, std::ios::beg); else if(depth!=0) _fseeki64( Disk, RDO + bs.bpb.bpbRootEntries*sizeof(DirectoryEntry) + (clusterNum-2) * sizeofRead, SEEK_SET ); //Disk.seekg(RDO + bs.bpb.bpbRootEntries*sizeof(DirectoryEntry) + (clusterNum-2) * sizeofRead, std::ios::beg); else _fseeki64( Disk, RDO, SEEK_SET ); //Disk.seekg(RDO , std::ios::beg); if(fat_type == 16 && depth ==0) { fread((char *)buffer2, sizeofFolderRead, 1, Disk); //Disk.read((char *)buffer2, sizeofFolderRead); break; } else fread( (char *)buffer2+FolderClusterCounter*sizeofRead, sizeofRead, 1, Disk); //Disk.read((char *)buffer2+FolderClusterCounter*sizeofRead, sizeofRead); clusterNum = getNext(fat, clusterNum); FolderClusterCounter++; } clearAll(possibleDestNameList, fileNameList, possibleDestPtrList, filePtrList); getDirContent(buffer2+additionalshift, possibleDestNameList, possibleDestPtrList, fileNameList, filePtrList, 0); show_Console(); break; } k++; } /*------------------------------------------------------------------------------------*/ if(!moveTo.compare("..")) { if(depth>0) depth--; int iter = 0; if(depth==0) additionalshift = 0; int countSlash = 0; while(currDir[iter]) { if((currDir[iter])=='\\') countSlash++; if(countSlash==(depth+2)) { currDir[iter+1] = 0; break; } iter++; } cDir = upDR[depth]; clearAll(possibleDestNameList, fileNameList, possibleDestPtrList, filePtrList); free(buffer2); buffer2 = 0; FolderClusterCounter = 0; clusterNum = cDir+2; while(clusterNum*sizeFat < SPF*bs.bpb.bpbBytesPerSector) { if(fat_type == 16&& depth ==0) sizeofFolderRead = bs.bpb.bpbRootEntries*sizeof(DirectoryEntry); else sizeofFolderRead = (FolderClusterCounter+1)*sizeofRead; buffer2 = (byte *)realloc(buffer2, sizeofFolderRead); if(fat_type == 32) _fseeki64( Disk, RDO + (clusterNum-2) * sizeofRead, SEEK_SET ); //Disk.seekg(RDO + (clusterNum-2) * sizeofRead, std::ios::beg); else if(depth!=0) _fseeki64( Disk, RDO + bs.bpb.bpbRootEntries*sizeof(DirectoryEntry) + (clusterNum-2) * sizeofRead, SEEK_SET ); //Disk.seekg(RDO + bs.bpb.bpbRootEntries*sizeof(DirectoryEntry) + (clusterNum-2) * sizeofRead, std::ios::beg); else _fseeki64( Disk, RDO, SEEK_SET ); //Disk.seekg(RDO , std::ios::beg); if(fat_type == 16 && depth ==0) { fread( (char *)buffer2, sizeofFolderRead, 1, Disk); //Disk.read((char *)buffer2, sizeofFolderRead); break; } else fread( (char *)buffer2+FolderClusterCounter*sizeofRead, sizeofRead, 1, Disk); //Disk.read((char *)buffer2+FolderClusterCounter*sizeofRead, sizeofRead); clusterNum = getNext(fat, clusterNum); FolderClusterCounter++; } getDirContent(buffer2+additionalshift, possibleDestNameList, possibleDestPtrList, fileNameList, filePtrList, 0); show_Console(); } } /*-----------------------------------------------------------------------------------------*/ if(!command.compare("cp")) { char c = getchar(); getline(std::cin, copy, '\n'); setlocale(LC_CTYPE, ""); decode(const_cast<char *>(copy.c_str())); lower(copy); int k = 0; clearAll(possibleDestNameList, fileNameList, possibleDestPtrList, filePtrList); free(buffer2); buffer2 = 0; FolderClusterCounter = 0; clusterNum = cDir+2; while(clusterNum*sizeFat < SPF*bs.bpb.bpbBytesPerSector) { if(fat_type == 16&& depth ==0) sizeofFolderRead = bs.bpb.bpbRootEntries*sizeof(DirectoryEntry); else sizeofFolderRead = (FolderClusterCounter+1)*sizeofRead; buffer2 = (byte *)realloc(buffer2, sizeofFolderRead); if(fat_type == 32) _fseeki64( Disk, RDO + (clusterNum-2) * sizeofRead, SEEK_SET ); //Disk.seekg(RDO + (clusterNum-2) * sizeofRead, std::ios::beg); else if(depth!=0) _fseeki64( Disk, RDO + bs.bpb.bpbRootEntries*sizeof(DirectoryEntry) + (clusterNum-2) * sizeofRead, SEEK_SET ); //Disk.seekg(RDO + bs.bpb.bpbRootEntries*sizeof(DirectoryEntry) + (clusterNum-2) * sizeofRead, std::ios::beg); else _fseeki64( Disk, RDO, SEEK_SET ); //Disk.seekg(RDO , std::ios::beg); if(fat_type == 16 && depth ==0) { fread( (char *)buffer2, sizeofFolderRead, 1, Disk); //Disk.read((char *)buffer2, sizeofFolderRead); break; } else fread( (char *)buffer2+FolderClusterCounter*sizeofRead, sizeofRead, 1, Disk); //Disk.read((char *)buffer2+FolderClusterCounter*sizeofRead, sizeofRead); clusterNum = getNext(fat, clusterNum); FolderClusterCounter++; } getDirContent(buffer2+additionalshift, possibleDestNameList, possibleDestPtrList, fileNameList, filePtrList, 0); while(fileNameList[k]) { std::string s (fileNameList[k]); lower(s); //std::cout<<copy<<" "<<s<<"\n"; //system("pause"); if(!copy.compare(s)) { std::ofstream fileCopy (fileNameList[k], std::ios::out | std::ios::binary); dword fileOffset = 0; dword sizeofWrite = sizeofRead; if (sizeofWrite>filePtrList[k+500]) sizeofWrite=filePtrList[k+500]; if(fat_type==16) fileOffset = bs.bpb.bpbRootEntries*sizeof(DirectoryEntry) + filePtrList[k]*bs.bpb.bpbSectorsPerCluster*bs.bpb.bpbBytesPerSector; else fileOffset = filePtrList[k]*bs.bpb.bpbSectorsPerCluster*bs.bpb.bpbBytesPerSector; _fseeki64( Disk, RDO + fileOffset, SEEK_SET ); //Disk.seekg(RDO + fileOffset, std::ios::beg); fread( (char*)buffer3, sizeofRead, 1, Disk); //Disk.read((char*)buffer3, sizeofRead); if(fileCopy.is_open()) fileCopy.write((char *)buffer3 ,sizeofWrite); word addressLow = 0; word addressHigh = 0; dword address = 0; dword numWrite = 2; dword numClast = filePtrList[k]+2; while(sizeofRead*numWrite < filePtrList[k+500]) { if(fat_type==16) memcpy(&addressLow, fat+sizeFat*numClast, 2); else { memcpy(&addressLow, fat+sizeFat*numClast, 2); memcpy(&addressHigh, fat+sizeFat*numClast+2, 1); } address = (addressLow | (addressHigh << 16))-2; if(fat_type==16) fileOffset = bs.bpb.bpbRootEntries*sizeof(DirectoryEntry) + address*bs.bpb.bpbSectorsPerCluster*bs.bpb.bpbBytesPerSector; else fileOffset = address*bs.bpb.bpbSectorsPerCluster*bs.bpb.bpbBytesPerSector; _fseeki64( Disk, RDO + fileOffset, SEEK_SET ); //Disk.seekg(RDO + fileOffset, std::ios::beg); fread( (char*)buffer3, sizeofRead, 1, Disk); //Disk.read((char*)buffer3, sizeofRead); if(fileCopy.is_open()) fileCopy.write((char *)buffer3 ,sizeofWrite); numWrite++; numClast = address + 2; } if(filePtrList[k+500]>sizeofRead*(numWrite-1)) { if(fat_type==16) memcpy(&addressLow, fat+sizeFat*numClast, 2); else { memcpy(&addressLow, fat+sizeFat*numClast, 2); memcpy(&addressHigh, fat+sizeFat*numClast+2, 2); } address = (addressLow | (addressHigh << 16))-2; if(fat_type==16) fileOffset = bs.bpb.bpbRootEntries*sizeof(DirectoryEntry) + address*bs.bpb.bpbSectorsPerCluster*bs.bpb.bpbBytesPerSector; else fileOffset = address*bs.bpb.bpbSectorsPerCluster*bs.bpb.bpbBytesPerSector; _fseeki64( Disk, RDO + fileOffset, SEEK_SET ); //Disk.seekg(RDO + fileOffset, std::ios::beg); fread( (char*)buffer3, sizeofRead, 1, Disk); //Disk.read((char*)buffer3, sizeofRead); if(fileCopy.is_open()) fileCopy.write((char *)buffer3 ,filePtrList[k+500]-sizeofWrite*(numWrite-1)); } break; } k++; } show_Console(); } } /*----------------------------------------------------------------------------------------------*/ fclose(Disk); //Disk.close(); free(buffer2); free(buffer3); free(fat); return 0; } | ||||||
|
Хэдер #include <sstream> #include <locale> typedef unsigned short word; typedef unsigned char byte; typedef unsigned long dword; char fat_type = 0, sizeFat = 0; char RootDirName[100] = {0}; char currDir[2000] = {0}; char lfndName[400]={0}; struct DateTime { unsigned Year, Month, Day; unsigned Hour, Minute, Second; }; struct DirectoryEntry { char FileName[8]; char Extension[3]; enum {ReadOnly=0x1, Hidden=0x2, System=0x4, Volume=0x8, Directory=0x10}; byte attribute; byte reserved0; byte CreationTime10Milliseconds; word CreationTime, CreationDate; word AccessDate; word Node_high; word UpdateTime, UpdateDate; word Node_low; dword FileSize; bool IsAtEnd() const; bool IsDeleted() const; bool IsLFN() const; bool IsDirectory() const; DateTime GetCreationDate() const; DateTime GetLastAccessDate() const; DateTime GetLastModificationDate() const; }; DateTime UnpackDateTime(word date, word time) { DateTime d; d.Year =(date>>9) + 1980; d.Month=(date>>5) & 0xF; d.Day = date & 0x1F; d.Hour =(time>>11); d.Minute=(time>>5)& 0x3F; d.Second=(time & 0x1F)*2; return d; } struct BPB { word bpbBytesPerSector; byte bpbSectorsPerCluster; word bpbReservedSectors; byte bpbNumberOfFATs; word bpbRootEntries; word bpbTotalSectors; byte bpbMedia; word bpbSectorsPerFAT; word bpbSectorsPerTrack; word bpbHeadsPerCylinder; dword bpbHiddenSectors; dword bpbTotalSectorsBig; }; struct BootSector { byte bsJmp[3]; byte bsOemName[8]; BPB bpb; }; struct ExtBootSector { byte bsDriveNumber, bsUnused, bsExtBootSignature; dword bsSerialNumber; byte bsVolumeLabel[11]; byte bsFileSystem[8]; }; struct ExtBootSector32 { dword bpb32SectorsPerFAT; word bpb32Flags; word bpb32Version; dword bpb32RootCluster; word bpb32InfoSector; word bpb32BootBackupStart; byte bpb32Reserved[12]; ExtBootSector ebs16; }; struct LFNDirectoryEntry { byte seqNum; byte name1[10]; byte attribute; byte type; byte checksum; byte name2[12]; word firstCluster; byte name3[4]; }; void showDirectoryContent(char ** possibleDestNameList, char** fileNameList, int depth) { int i = 0; while(possibleDestNameList[i]) { std::cout<<possibleDestNameList[i]<<"\\"<<std::endl; i++; } i = 0; while(fileNameList[i]) { std::cout<<fileNameList[i]<<std::endl; i++; } } void DrowLine(int len){for(int i = 0; i<len; i++ ){putchar('-');}} void show_Console() { system("cls"); word Width = 80; DrowLine(Width); std::cout<<"Commands:"<<std::endl; std::cout<<" cls - Clear screen.\n ls - List files in current directory. \"ls help\" for info.\n cd - Change directory. \"cd help\" for info.\n \"cp $file$\" - Copy file to folder of the app.\n exit | quit | q - Close.\n"; DrowLine(Width); std::cout<<currDir; std::cout<<std::endl; DrowLine(Width); } void utf16ToASCII(int iter, char* lfndName, int numberOfLFND, word first, word last, char shift) { if(last==0) lfndName[13*(numberOfLFND-1)+shift+iter] = (int)first; else { if(last==0x04) { if(first == 1) lfndName[13*(numberOfLFND-1)+shift+iter] = -88; if(first == 0x51) lfndName[13*(numberOfLFND-1)+shift+iter] = -72; if(first< 0x30 && first> 0xf) lfndName[13*(numberOfLFND-1)+shift+iter] = -64+(first-0x10); if(first< 0x50 && first> 0x2f) lfndName[13*(numberOfLFND-1)+shift+iter] = -32+(first-0x30); } } } void getDirContent(byte* Dir, char ** possibleDestNameList, dword * possibleDestPtrList, char** fileNameList, dword * filePtrList, char sz) { int num = 0, posD = 0, posF = 0, cleanbuf = 0; char ff = 0; DirectoryEntry sfn= {0}; memcpy(&sfn, Dir, sizeof(sfn)); while(!sfn.IsAtEnd()) { int j = 0; int k = 0; std::string sizeOfFile, date, time, date2, time2; std::stringstream Buf, Buf2, Buf3, Buf4, Buf5; if(sfn.IsLFN()) { ff = 0; LFNDirectoryEntry lfnd; lfnd = reinterpret_cast<const LFNDirectoryEntry&>(sfn); word numberOfLFND = lfnd.seqNum & 0xF; while(numberOfLFND!=1) { for(int iter = 0;iter<5;iter++) utf16ToASCII(iter, lfndName, numberOfLFND, lfnd.name1[2*iter], lfnd.name1[2*iter+1], 0); for(int iter = 0;iter<6;iter++) utf16ToASCII(iter, lfndName, numberOfLFND, lfnd.name2[2*iter], lfnd.name2[2*iter+1], 5); for(int iter = 0;iter<2;iter++) utf16ToASCII(iter, lfndName, numberOfLFND, lfnd.name3[2*iter], lfnd.name3[2*iter+1], 11); num++; memcpy(&lfnd, Dir+num*sizeof(sfn), sizeof(sfn)); numberOfLFND = lfnd.seqNum & 0xF; } for(int iter = 0;iter<5;iter++) utf16ToASCII(iter, lfndName, numberOfLFND, lfnd.name1[2*iter], lfnd.name1[2*iter+1], 0); for(int iter = 0;iter<6;iter++) utf16ToASCII(iter, lfndName, numberOfLFND, lfnd.name2[2*iter], lfnd.name2[2*iter+1], 5); for(int iter = 0;iter<2;iter++) utf16ToASCII(iter, lfndName, numberOfLFND, lfnd.name3[2*iter], lfnd.name3[2*iter+1], 11); num++; memcpy(&sfn, Dir+num*sizeof(sfn), sizeof(sfn)); j = strlen(lfndName); word nodeH = 0; if(fat_type == 32) nodeH = sfn.Node_high; dword ofst = (dword)((sfn.Node_low | (nodeH << 16)))-2; if(sfn.IsDirectory()) { possibleDestPtrList[posD] = ofst; possibleDestNameList[posD] = (char *)realloc(possibleDestNameList[posD], j+10); memcpy(possibleDestNameList[posD], lfndName, j+1); posD++; }else { filePtrList[posF]=ofst; filePtrList[posF+500]=sfn.FileSize; fileNameList[posF] = (char *)realloc(fileNameList[posF], j+10); memcpy(fileNameList[posF], lfndName, j+1); posF++; Buf << sfn.FileSize; Buf >> sizeOfFile; Buf2 << sfn.GetCreationDate().Day<<"."<<sfn.GetCreationDate().Month<<"."<<sfn.GetCreationDate().Year; Buf2 >> date; Buf3 << sfn.GetCreationDate().Hour<<":"<<sfn.GetCreationDate().Minute<<":"<<sfn.GetCreationDate().Second; Buf3 >> time; Buf4 << sfn.GetLastModificationDate().Day<<"."<<sfn.GetLastModificationDate().Month<<"."<<sfn.GetLastModificationDate().Year; Buf4 >> date2; Buf5 << sfn.GetLastModificationDate().Hour<<":"<<sfn.GetLastModificationDate().Minute<<":"<<sfn.GetLastModificationDate().Second; Buf5 >> time2; j--; ff = 1; } cleanbuf = 0; while(lfndName[cleanbuf]) { lfndName[cleanbuf] = 0; cleanbuf++; } } else { ff = 0; if(!sfn.IsDeleted() && (sfn.attribute!=sfn.Volume)) { for(int i = 0; i < 8; i++) if(sfn.FileName[i]==' ') { j = i; break; } else { if(sfn.FileName[i] >= 'A' && sfn.FileName[i] <= 'Z') sfn.FileName[i] = sfn.FileName[i]+'a'-'A'; if(i == 7) j = 8; } word nodeH = 0; if(fat_type == 32) nodeH = sfn.Node_high; dword ofst = (dword)((sfn.Node_low | (nodeH << 16))-2); if(sfn.IsDirectory()) { possibleDestPtrList[posD] = ofst; possibleDestNameList[posD] = (char *)realloc(possibleDestNameList[posD], j+5); memcpy(possibleDestNameList[posD], sfn.FileName, j); memcpy(possibleDestNameList[posD]+j, "\0", 1); posD++; ff=0; } else { filePtrList[posF] = ofst; filePtrList[posF+500] = sfn.FileSize; for(int i = 0; i < 4; i++) if(sfn.Extension[i]==' ') { k = i; break; } else { if(sfn.Extension[i] >= 'A' && sfn.Extension[i] <= 'Z') sfn.Extension[i] = sfn.Extension[i]+'a'-'A'; } fileNameList[posF] = (char *)realloc(fileNameList[posF], j+5); memcpy(fileNameList[posF],sfn.FileName, j); if(k!= 0) { memcpy(fileNameList[posF]+j, ".", 1); memcpy(fileNameList[posF]+j+1, sfn.Extension, k); memcpy(fileNameList[posF]+j+k+1,"\0", 1); } else memcpy(fileNameList[posF]+j,"\0", 1); posF++; Buf << sfn.FileSize; Buf >> sizeOfFile; Buf2 << sfn.GetCreationDate().Day<<"."<<sfn.GetCreationDate().Month<<"."<<sfn.GetCreationDate().Year; Buf2 >> date; Buf3 << sfn.GetCreationDate().Hour<<":"<<sfn.GetCreationDate().Minute<<":"<<sfn.GetCreationDate().Second; Buf3 >> time; Buf4 << sfn.GetLastModificationDate().Day<<"."<<sfn.GetLastModificationDate().Month<<"."<<sfn.GetLastModificationDate().Year; Buf4 >> date2; Buf5 << sfn.GetLastModificationDate().Hour<<":"<<sfn.GetLastModificationDate().Minute<<":"<<sfn.GetLastModificationDate().Second; Buf5 >> time2; ff = 1; } } } if (sz!=0 && posF>0 && ff==1) { int i = j+k+1; if (k==0) i = j; fileNameList[posF -1] = (char *)realloc(fileNameList[posF -1], i+5); memcpy(fileNameList[posF -1]+i, " ", 2); i = i+2; switch(sz) { case 1: fileNameList[posF -1] = (char *)realloc(fileNameList[posF -1], i+sizeOfFile.size()+5); memcpy(fileNameList[posF -1]+i, sizeOfFile.c_str(), sizeOfFile.size()+1); break; case 2: fileNameList[posF -1] = (char *)realloc(fileNameList[posF -1], i+date.size()+time.size()+5); memcpy(fileNameList[posF -1]+i, date.c_str(), date.size()); memcpy(fileNameList[posF -1]+i+date.size(), " ", 1); memcpy(fileNameList[posF -1]+i+date.size() +1 , time.c_str(), time.size()+1); break; case 3: fileNameList[posF -1] = (char *)realloc(fileNameList[posF-1], i+date2.size()+time2.size()+5); memcpy(fileNameList[posF -1]+i, date2.c_str(), date2.size()); memcpy(fileNameList[posF -1]+i+date2.size(), " ", 1); memcpy(fileNameList[posF -1]+i+date2.size() +1 , time2.c_str(), time2.size()+1); break; } } num++; memcpy(&sfn, Dir+num*sizeof(sfn), sizeof(sfn)); } } void clearAll(char ** possibleDestNameList, char ** fileNameList, dword * possibleDestPtrList, dword * filePtrList) { int i = 0; while(possibleDestNameList[i]) { free(possibleDestNameList[i]); possibleDestNameList[i] = 0; possibleDestPtrList[i] = 0; i++; } i = 0; while(fileNameList[i]) { free(fileNameList[i]); fileNameList[i] = 0; filePtrList[i] = 0; filePtrList[i+500] = 0; i++; } } void decode(char * str) { for(word iter=0; iter<strlen(str);iter++) { if(str[iter]<0) { if(str[iter]==-15) { str[iter]=-72; continue; } if(str[iter]==-16) { str[iter]=-88; continue; } if(str[iter]>=-32 && str[iter]<=-17) { str[iter]=-16 + (32+str[iter]); continue; } if(str[iter]>=-96 && str[iter]<=-81) { str[iter]=-32 + (96+str[iter]); continue; } if(str[iter]>=-128 && str[iter]<=-97) { str[iter]=-64 + (128+str[iter]); continue; } } } } dword getNext(byte* fat , dword clusterNum) { word Low = 0, High = 0; if(fat_type == 16) memcpy(&Low, fat+sizeFat*clusterNum, 2); else { memcpy(&Low, fat+sizeFat*clusterNum, 2); memcpy(&High, fat+sizeFat*clusterNum+2, 1); } clusterNum = (Low | (High << 16)); return clusterNum; } void lower(std::string& s) { std::locale loc (""); std::string::iterator i = s.begin(); std::string::iterator end = s.end(); while (i != end) { *i = std::tolower(*i, loc); i++; } } | ||||||
|
Посмотрел. Словил мозговой оргазм от обилия комментариев! Без них было бы ничего не понятно, честное пионерское! Всегда также пиши комментарии в каждой строке кода, молодец, респект и уважуха! Кислотно-голубой цвет подсветки доставляет. Больше пока ничего сказать не могу... З.Ы. Ну, вы поняли, о чём я... Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп! | ||||||
|
Да с комментами перебор,переписывал потоки,оставил на всякий случай,забыл убрать кислотный икскодовский,но тоже верно не учел | ||||||
|
Цитата (Helloworld): оставил на всякий случай,забыл убрать Ты издеваешься? Или мой сарказм не понимаешь? Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп! | ||||||
|
честно?не особо | ||||||
|
// // main.cpp #pragma pack(1) #include <iostream> #include <fstream> #include "Header.h" DateTime UnpackDateTime(word date, word time); void showDirectoryContent(char ** possibleDestNameList, char** fileNameList, int depth); void DrowLine(int len); void show_Console(); void getDirContent(byte* Dir, char ** possibleDestNameList, dword * possibleDestPtrList, char ** fileNameList, dword* filePtrList, char sz); void clearAll(char ** possibleDestNameList, char ** fileNameList,dword * possibleDestPtrList, dword * filePtrList); void decode(char * str); dword getNext(byte* fat , dword clusterNum); void lower(std::string& s); bool DirectoryEntry::IsLFN() const { return !IsDeleted() && !IsAtEnd() && (attribute==0x0F && reserved0 == 0x0 && Node_low == 0x0); } bool DirectoryEntry::IsDirectory() const { return !IsDeleted() && !IsAtEnd() && (attribute & Directory); } bool DirectoryEntry::IsAtEnd() const { return FileName[0]==0; } bool DirectoryEntry::IsDeleted() const { return (unsigned char)FileName[0]==0xE5; } DateTime DirectoryEntry::GetCreationDate() const { return UnpackDateTime(CreationDate, CreationTime); } DateTime DirectoryEntry::GetLastAccessDate() const { return UnpackDateTime(AccessDate, 0); } DateTime DirectoryEntry::GetLastModificationDate() const { return UnpackDateTime(UpdateDate, UpdateTime); } int main() { byte* buffer = 0; byte* buffer2 = 0; byte* buffer3 = 0; byte* fat = 0; char dest[]="\\\\.\\F:"; char * possibleDestNameList[500] = {0}; char * fileNameList[500] = {0}; dword possibleDestPtrList[500] = {0}; dword filePtrList[1000] ={0}; dword upDR[100] = {0}; std::string command, moveTo, listingAtr, copy; char a = 0; char Letter ='F'; int depth = 0; int k = 0; int iter1 = 0; int num=0; int additionalshift = 0; dword bytesReturned = 0, fbufferSize = 0, fbufferSize2 = 0, sbufferSize = 0, max = 0, SC = 0, SPF = 0, TS = 0, RDO = 0, cDir = 0; long double forCeil = 0, SSA = 0, forFloor = 0; BootSector bs = {0}; ExtBootSector32 ebs32 = {0}; ExtBootSector ebs = {0}; std::cout<<"Enter the device letter:"; std::cin >> dest[4]; FILE * Disk = fopen(dest, "rb"); if(Disk == NULL) { std::cout << "Unable to open disk" << std::endl; return 1; } //std::ifstream Disk (dest, std::ios::in | std::ios::binary); buffer = (byte *)malloc(100); fread( (char *)buffer, 100, 1, Disk); //Disk.read((char *)buffer, 100); memcpy(&bs, buffer, sizeof(bs)); fbufferSize = bs.bpb.bpbBytesPerSector*bs.bpb.bpbSectorsPerTrack; buffer = (byte *)realloc(buffer, fbufferSize); _fseeki64( Disk, 0, SEEK_SET ); //Disk.seekg(0, std::ios::beg); fread( (char *)buffer, fbufferSize, 1, Disk); //Disk.read((char *)buffer, fbufferSize); TS = bs.bpb.bpbTotalSectors; if (TS == 0) TS = bs.bpb.bpbTotalSectorsBig; forCeil = (32*bs.bpb.bpbRootEntries)/bs.bpb.bpbBytesPerSector; SSA = bs.bpb.bpbReservedSectors+(bs.bpb.bpbNumberOfFATs*bs.bpb.bpbSectorsPerFAT)+/*ceil(forCeil)*/int(forCeil); SC = bs.bpb.bpbSectorsPerCluster; forFloor = (TS-SSA)/SC; max = 1 + dword(forFloor); if(max < 4085) { fat_type = 12; } else { if(max < 65525) { fat_type = 16; } else { fat_type = 32; } } std::cout << int (bs.bpb.bpbNumberOfFATs) << '\n'; if (fat_type==32) memcpy(&ebs32, buffer + sizeof(bs), sizeof(ebs32)); else memcpy(&ebs, buffer + sizeof(bs), sizeof(ebs)); if (fat_type == 12) { std::cout<<"Fat12 is not supported."<<std::endl; system("pause"); return -4; } if(fat_type == 32) { SPF = ebs32.bpb32SectorsPerFAT; sizeFat = 4; } else { SPF = bs.bpb.bpbSectorsPerFAT; sizeFat = 2; } free(buffer); RDO = bs.bpb.bpbReservedSectors * bs.bpb.bpbBytesPerSector + SPF * bs.bpb.bpbBytesPerSector * bs.bpb.bpbNumberOfFATs; fat = (byte *)malloc(SPF*bs.bpb.bpbBytesPerSector); _fseeki64( Disk, bs.bpb.bpbReservedSectors * bs.bpb.bpbBytesPerSector, SEEK_SET ); //Disk.seekg(bs.bpb.bpbReservedSectors * bs.bpb.bpbBytesPerSector, std::ios::beg); fread( (char *)fat, SPF*bs.bpb.bpbBytesPerSector, 1, Disk); //Disk.read((char *)fat, SPF*bs.bpb.bpbBytesPerSector); dword sizeofRead = bs.bpb.bpbBytesPerSector *bs.bpb.bpbSectorsPerCluster; dword sizeofFolderRead = sizeofRead; buffer2 = (byte *)malloc(sizeofRead); buffer3 = (byte *)malloc(sizeofRead); strncpy(currDir, RootDirName, strlen(RootDirName)+1); setlocale(LC_CTYPE, ""); dword clusterNum = 2; int FolderClusterCounter = 0; if(fat_type == 32) { while(clusterNum*sizeFat < SPF*bs.bpb.bpbBytesPerSector) { sizeofFolderRead = (FolderClusterCounter+1)*sizeofRead; buffer2 = (byte *)realloc(buffer2, sizeofFolderRead); _fseeki64( Disk, RDO + (clusterNum-2) * sizeofRead, SEEK_SET ); //Disk.seekg(RDO + (clusterNum-2) * sizeofRead, std::ios::beg); fread( (char *)buffer2+FolderClusterCounter*sizeofRead, sizeofRead, 1, Disk); //Disk.read((char *)buffer2+FolderClusterCounter*sizeofRead, sizeofRead); clusterNum = getNext(fat, clusterNum); FolderClusterCounter++; } } else { sizeofFolderRead = bs.bpb.bpbRootEntries*32; buffer2 = (byte *)realloc(buffer2, sizeofFolderRead); _fseeki64( Disk, RDO, SEEK_SET ); //Disk.seekg(RDO, std::ios::beg); fread( (char *)buffer2, sizeofFolderRead, 1, Disk); //Disk.read((char *)buffer2, sizeofFolderRead); } getDirContent(buffer2, possibleDestNameList, possibleDestPtrList, fileNameList, filePtrList, 0); show_Console(); while(true) { std::cin>>command; if(!command.compare("cls")) { system("cls"); show_Console(); } if(!command.compare("ls")) { char c = getchar(); std::cout<<(int)c<<std::endl; if (c==' '){ clearAll(possibleDestNameList, fileNameList, possibleDestPtrList, filePtrList); std::cin>>listingAtr; show_Console(); free(buffer2); buffer2 = 0; FolderClusterCounter = 0; clusterNum = cDir+2; while(clusterNum*sizeFat < SPF*bs.bpb.bpbBytesPerSector) { if(fat_type == 16&& depth ==0) sizeofFolderRead = bs.bpb.bpbRootEntries*sizeof(DirectoryEntry); else sizeofFolderRead = (FolderClusterCounter+1)*sizeofRead; buffer2 = (byte *)realloc(buffer2, sizeofFolderRead); if(fat_type == 32) _fseeki64( Disk, RDO + (clusterNum-2) * sizeofRead, SEEK_SET ); //Disk.seekg(RDO + (clusterNum-2) * sizeofRead, std::ios::beg); else if(depth!=0) _fseeki64( Disk, RDO + bs.bpb.bpbRootEntries*sizeof(DirectoryEntry) + (clusterNum-2) * sizeofRead, SEEK_SET ); //Disk.seekg(RDO + bs.bpb.bpbRootEntries*sizeof(DirectoryEntry) + (clusterNum-2) * sizeofRead, std::ios::beg); else _fseeki64( Disk, RDO, SEEK_SET ); //Disk.seekg(RDO , std::ios::beg); if(fat_type == 16 && depth ==0) { fread( (char *)buffer2, sizeofFolderRead, 1, Disk); //Disk.read((char *)buffer2, sizeofFolderRead); break; } else fread( (char *)buffer2+FolderClusterCounter*sizeofRead, sizeofRead, 1, Disk); //Disk.read((char *)buffer2+FolderClusterCounter*sizeofRead, sizeofRead); clusterNum = getNext(fat, clusterNum); FolderClusterCounter++; } if(!listingAtr.compare("-s")) { getDirContent(buffer2+additionalshift, possibleDestNameList, possibleDestPtrList, fileNameList, filePtrList, 1); showDirectoryContent(possibleDestNameList, fileNameList, depth); continue; } if(!listingAtr.compare("-ct")) { getDirContent(buffer2+additionalshift, possibleDestNameList, possibleDestPtrList, fileNameList, filePtrList, 2); showDirectoryContent(possibleDestNameList, fileNameList, depth); continue; } if(!listingAtr.compare("-mt")) { getDirContent(buffer2+additionalshift, possibleDestNameList, possibleDestPtrList, fileNameList, filePtrList, 3); showDirectoryContent(possibleDestNameList, fileNameList, depth); continue; } if(!listingAtr.compare("help")) { show_Console(); std::cout<<"\n\"ls\" shows files in the current directory.\n\"ls -s\" print size of files.\n\"ls -ct\" print creation time of files.\n\"ls -mt\" print last modification time of files.\n\n"; system("pause"); show_Console(); continue; } } clearAll(possibleDestNameList, fileNameList, possibleDestPtrList, filePtrList); show_Console(); free(buffer2); buffer2 = 0; FolderClusterCounter = 0; clusterNum = cDir+2; while(clusterNum*sizeFat < SPF*bs.bpb.bpbBytesPerSector) { if(fat_type == 16&& depth ==0) sizeofFolderRead = bs.bpb.bpbRootEntries*sizeof(DirectoryEntry); else sizeofFolderRead = (FolderClusterCounter+1)*sizeofRead; buffer2 = (byte *)realloc(buffer2, sizeofFolderRead); if(fat_type == 32) _fseeki64( Disk, RDO + (clusterNum-2) * sizeofRead, SEEK_SET ); //Disk.seekg(RDO + (clusterNum-2) * sizeofRead, std::ios::beg); else if(depth!=0) _fseeki64( Disk, RDO + bs.bpb.bpbRootEntries*sizeof(DirectoryEntry) + (clusterNum-2) * sizeofRead, SEEK_SET ); //Disk.seekg(RDO + bs.bpb.bpbRootEntries*sizeof(DirectoryEntry) + (clusterNum-2) * sizeofRead, std::ios::beg); else _fseeki64( Disk, RDO, SEEK_SET ); //Disk.seekg(RDO , std::ios::beg); if(fat_type == 16 && depth ==0) { fread( (char *)buffer2,sizeofFolderRead, 1, Disk); //Disk.read((char *)buffer2, sizeofFolderRead); break; } else fread( (char *)buffer2+FolderClusterCounter*sizeofRead, sizeofRead, 1, Disk); //Disk.read((char *)buffer2+FolderClusterCounter*sizeofRead, sizeofRead); clusterNum = getNext(fat, clusterNum); FolderClusterCounter++; } getDirContent(buffer2+additionalshift, possibleDestNameList, possibleDestPtrList, fileNameList, filePtrList, 0); showDirectoryContent(possibleDestNameList, fileNameList, depth); } if(!command.compare("q")) break; if(!command.compare("cd")) { char c = getchar(); getline(std::cin, moveTo, '\n'); setlocale(LC_CTYPE, ""); decode(const_cast<char *>(moveTo.c_str())); lower(moveTo); if(!moveTo.compare("help")) { show_Console(); std::cout<<"\n\"cd \\\" will move you to root directory.\n\"cd ..\" will move you up one directory.\n\"cd $subfolder$\" will move you in a subdirectory called $subfolder$.\n\n"; system("pause"); show_Console(); } if(!moveTo.compare("\\")) { for(int i = depth; i>0; i--) { upDR[i]=0; } additionalshift=0; depth = 0; strncpy(currDir, RootDirName, strlen(RootDirName) +1); cDir = 0; free(buffer2); buffer2 = 0; FolderClusterCounter = 0; clusterNum = cDir+2; if(fat_type == 32) { while(clusterNum*sizeFat < SPF*bs.bpb.bpbBytesPerSector) { sizeofFolderRead = (FolderClusterCounter+1)*sizeofRead; buffer2 = (byte *)realloc(buffer2, sizeofFolderRead); _fseeki64( Disk, RDO + (clusterNum-2) * sizeofRead, SEEK_SET ); //Disk.seekg(RDO + (clusterNum-2) * sizeofRead, std::ios::beg); fread( (char *)buffer2+FolderClusterCounter*sizeofRead, sizeofRead, 1, Disk); //Disk.read((char *)buffer2+FolderClusterCounter*sizeofRead, sizeofRead); clusterNum = getNext(fat, clusterNum); FolderClusterCounter++; } } else { sizeofFolderRead = bs.bpb.bpbRootEntries*32; buffer2 = (byte *)realloc(buffer2, sizeofFolderRead); _fseeki64( Disk, RDO, SEEK_SET ); //Disk.seekg(RDO, std::ios::beg); fread( (char *)buffer2, sizeofFolderRead, 1, Disk); //Disk.read((char *)buffer2, sizeofFolderRead); } upDR[depth] = 0; clearAll(possibleDestNameList, fileNameList, possibleDestPtrList, filePtrList); getDirContent(buffer2, possibleDestNameList, possibleDestPtrList, fileNameList, filePtrList, 0); show_Console(); } int k = 0; while(possibleDestNameList[k]){ std::string s (possibleDestNameList[k]); lower(s); if(!moveTo.compare(s)) { depth++; upDR[depth-1] = cDir; strncat(currDir, possibleDestNameList[k], 400); strncat(currDir, "\\", 400); cDir = possibleDestPtrList[k]; additionalshift = 2*sizeof(DirectoryEntry); free(buffer2); buffer2 = 0; FolderClusterCounter = 0; clusterNum = cDir+2; while(clusterNum*sizeFat < SPF*bs.bpb.bpbBytesPerSector) { if(fat_type == 16&& depth ==0) sizeofFolderRead = bs.bpb.bpbRootEntries*sizeof(DirectoryEntry); else sizeofFolderRead = (FolderClusterCounter+1)*sizeofRead; buffer2 = (byte *)realloc(buffer2, sizeofFolderRead); if(fat_type == 32) _fseeki64( Disk, RDO + (clusterNum-2) * sizeofRead, SEEK_SET ); //Disk.seekg(RDO + (clusterNum-2) * sizeofRead, std::ios::beg); else if(depth!=0) _fseeki64( Disk, RDO + bs.bpb.bpbRootEntries*sizeof(DirectoryEntry) + (clusterNum-2) * sizeofRead, SEEK_SET ); //Disk.seekg(RDO + bs.bpb.bpbRootEntries*sizeof(DirectoryEntry) + (clusterNum-2) * sizeofRead, std::ios::beg); else _fseeki64( Disk, RDO, SEEK_SET ); //Disk.seekg(RDO , std::ios::beg); if(fat_type == 16 && depth ==0) { fread((char *)buffer2, sizeofFolderRead, 1, Disk); //Disk.read((char *)buffer2, sizeofFolderRead); break; } else fread( (char *)buffer2+FolderClusterCounter*sizeofRead, sizeofRead, 1, Disk); //Disk.read((char *)buffer2+FolderClusterCounter*sizeofRead, sizeofRead); clusterNum = getNext(fat, clusterNum); FolderClusterCounter++; } clearAll(possibleDestNameList, fileNameList, possibleDestPtrList, filePtrList); getDirContent(buffer2+additionalshift, possibleDestNameList, possibleDestPtrList, fileNameList, filePtrList, 0); show_Console(); break; } k++; } if(!moveTo.compare("..")) { if(depth>0) depth--; int iter = 0; if(depth==0) additionalshift = 0; int countSlash = 0; while(currDir[iter]) { if((currDir[iter])=='\\') countSlash++; if(countSlash==(depth+2)) { currDir[iter+1] = 0; break; } iter++; } cDir = upDR[depth]; clearAll(possibleDestNameList, fileNameList, possibleDestPtrList, filePtrList); free(buffer2); buffer2 = 0; FolderClusterCounter = 0; clusterNum = cDir+2; while(clusterNum*sizeFat < SPF*bs.bpb.bpbBytesPerSector) { if(fat_type == 16&& depth ==0) sizeofFolderRead = bs.bpb.bpbRootEntries*sizeof(DirectoryEntry); else sizeofFolderRead = (FolderClusterCounter+1)*sizeofRead; buffer2 = (byte *)realloc(buffer2, sizeofFolderRead); if(fat_type == 32) _fseeki64( Disk, RDO + (clusterNum-2) * sizeofRead, SEEK_SET ); //Disk.seekg(RDO + (clusterNum-2) * sizeofRead, std::ios::beg); else if(depth!=0) _fseeki64( Disk, RDO + bs.bpb.bpbRootEntries*sizeof(DirectoryEntry) + (clusterNum-2) * sizeofRead, SEEK_SET ); //Disk.seekg(RDO + bs.bpb.bpbRootEntries*sizeof(DirectoryEntry) + (clusterNum-2) * sizeofRead, std::ios::beg); else _fseeki64( Disk, RDO, SEEK_SET ); //Disk.seekg(RDO , std::ios::beg); if(fat_type == 16 && depth ==0) { fread( (char *)buffer2, sizeofFolderRead, 1, Disk); //Disk.read((char *)buffer2, sizeofFolderRead); break; } else fread( (char *)buffer2+FolderClusterCounter*sizeofRead, sizeofRead, 1, Disk); //Disk.read((char *)buffer2+FolderClusterCounter*sizeofRead, sizeofRead); clusterNum = getNext(fat, clusterNum); FolderClusterCounter++; } getDirContent(buffer2+additionalshift, possibleDestNameList, possibleDestPtrList, fileNameList, filePtrList, 0); show_Console(); } } if(!command.compare("cp")) { char c = getchar(); getline(std::cin, copy, '\n'); setlocale(LC_CTYPE, ""); decode(const_cast<char *>(copy.c_str())); lower(copy); int k = 0; clearAll(possibleDestNameList, fileNameList, possibleDestPtrList, filePtrList); free(buffer2); buffer2 = 0; FolderClusterCounter = 0; clusterNum = cDir+2; while(clusterNum*sizeFat < SPF*bs.bpb.bpbBytesPerSector) { if(fat_type == 16&& depth ==0) sizeofFolderRead = bs.bpb.bpbRootEntries*sizeof(DirectoryEntry); else sizeofFolderRead = (FolderClusterCounter+1)*sizeofRead; buffer2 = (byte *)realloc(buffer2, sizeofFolderRead); if(fat_type == 32) _fseeki64( Disk, RDO + (clusterNum-2) * sizeofRead, SEEK_SET ); //Disk.seekg(RDO + (clusterNum-2) * sizeofRead, std::ios::beg); else if(depth!=0) _fseeki64( Disk, RDO + bs.bpb.bpbRootEntries*sizeof(DirectoryEntry) + (clusterNum-2) * sizeofRead, SEEK_SET ); //Disk.seekg(RDO + bs.bpb.bpbRootEntries*sizeof(DirectoryEntry) + (clusterNum-2) * sizeofRead, std::ios::beg); else _fseeki64( Disk, RDO, SEEK_SET ); //Disk.seekg(RDO , std::ios::beg); if(fat_type == 16 && depth ==0) { fread( (char *)buffer2, sizeofFolderRead, 1, Disk); //Disk.read((char *)buffer2, sizeofFolderRead); break; } else fread( (char *)buffer2+FolderClusterCounter*sizeofRead, sizeofRead, 1, Disk); //Disk.read((char *)buffer2+FolderClusterCounter*sizeofRead, sizeofRead); clusterNum = getNext(fat, clusterNum); FolderClusterCounter++; } getDirContent(buffer2+additionalshift, possibleDestNameList, possibleDestPtrList, fileNameList, filePtrList, 0); while(fileNameList[k]) { std::string s (fileNameList[k]); lower(s); //std::cout<<copy<<" "<<s<<"\n"; //system("pause"); if(!copy.compare(s)) { std::ofstream fileCopy (fileNameList[k], std::ios::out | std::ios::binary); dword fileOffset = 0; dword sizeofWrite = sizeofRead; if (sizeofWrite>filePtrList[k+500]) sizeofWrite=filePtrList[k+500]; if(fat_type==16) fileOffset = bs.bpb.bpbRootEntries*sizeof(DirectoryEntry) + filePtrList[k]*bs.bpb.bpbSectorsPerCluster*bs.bpb.bpbBytesPerSector; else fileOffset = filePtrList[k]*bs.bpb.bpbSectorsPerCluster*bs.bpb.bpbBytesPerSector; _fseeki64( Disk, RDO + fileOffset, SEEK_SET ); //Disk.seekg(RDO + fileOffset, std::ios::beg); fread( (char*)buffer3, sizeofRead, 1, Disk); //Disk.read((char*)buffer3, sizeofRead); if(fileCopy.is_open()) fileCopy.write((char *)buffer3 ,sizeofWrite); word addressLow = 0; word addressHigh = 0; dword address = 0; dword numWrite = 2; dword numClast = filePtrList[k]+2; while(sizeofRead*numWrite < filePtrList[k+500]) { if(fat_type==16) memcpy(&addressLow, fat+sizeFat*numClast, 2); else { memcpy(&addressLow, fat+sizeFat*numClast, 2); memcpy(&addressHigh, fat+sizeFat*numClast+2, 1); } address = (addressLow | (addressHigh << 16))-2; if(fat_type==16) fileOffset = bs.bpb.bpbRootEntries*sizeof(DirectoryEntry) + address*bs.bpb.bpbSectorsPerCluster*bs.bpb.bpbBytesPerSector; else fileOffset = address*bs.bpb.bpbSectorsPerCluster*bs.bpb.bpbBytesPerSector; _fseeki64( Disk, RDO + fileOffset, SEEK_SET ); //Disk.seekg(RDO + fileOffset, std::ios::beg); fread( (char*)buffer3, sizeofRead, 1, Disk); //Disk.read((char*)buffer3, sizeofRead); if(fileCopy.is_open()) fileCopy.write((char *)buffer3 ,sizeofWrite); numWrite++; numClast = address + 2; } if(filePtrList[k+500]>sizeofRead*(numWrite-1)) { if(fat_type==16) memcpy(&addressLow, fat+sizeFat*numClast, 2); else { memcpy(&addressLow, fat+sizeFat*numClast, 2); memcpy(&addressHigh, fat+sizeFat*numClast+2, 2); } address = (addressLow | (addressHigh << 16))-2; if(fat_type==16) fileOffset = bs.bpb.bpbRootEntries*sizeof(DirectoryEntry) + address*bs.bpb.bpbSectorsPerCluster*bs.bpb.bpbBytesPerSector; else fileOffset = address*bs.bpb.bpbSectorsPerCluster*bs.bpb.bpbBytesPerSector; _fseeki64( Disk, RDO + fileOffset, SEEK_SET ); //Disk.seekg(RDO + fileOffset, std::ios::beg); fread( (char*)buffer3, sizeofRead, 1, Disk); //Disk.read((char*)buffer3, sizeofRead); if(fileCopy.is_open()) fileCopy.write((char *)buffer3 ,filePtrList[k+500]-sizeofWrite*(numWrite-1)); } break; } k++; } show_Console(); } } fclose(Disk); //Disk.close(); free(buffer2); free(buffer3); free(fat); return 0; } | ||||||
|
// // main.cpp // FAT // // Created by Алексей Григорьев on 07.06.12. // Copyright (c) 2012 terracot47@mail.ru. All rights reserved. // #pragma pack(1) #include <iostream> #include <fstream> #include "Header.h" DateTime UnpackDateTime(word date, word time); void showDirectoryContent(char ** possibleDestNameList, char** fileNameList, int depth); void DrowLine(int len); void show_Console(); void getDirContent(byte* Dir, char ** possibleDestNameList, dword * possibleDestPtrList, char ** fileNameList, dword* filePtrList, char sz); void clearAll(char ** possibleDestNameList, char ** fileNameList,dword * possibleDestPtrList, dword * filePtrList); void decode(char * str); dword getNext(byte* fat , dword clusterNum); void lower(std::string& s); bool DirectoryEntry::IsLFN() const { return !IsDeleted() && !IsAtEnd() && (attribute==0x0F && reserved0 == 0x0 && Node_low == 0x0); } bool DirectoryEntry::IsDirectory() const { return !IsDeleted() && !IsAtEnd() && (attribute & Directory); } bool DirectoryEntry::IsAtEnd() const { return FileName[0]==0; } bool DirectoryEntry::IsDeleted() const { return (unsigned char)FileName[0]==0xE5; } DateTime DirectoryEntry::GetCreationDate() const { return UnpackDateTime(CreationDate, CreationTime); } DateTime DirectoryEntry::GetLastAccessDate() const { return UnpackDateTime(AccessDate, 0); } DateTime DirectoryEntry::GetLastModificationDate() const { return UnpackDateTime(UpdateDate, UpdateTime); } int main() { byte* buffer = 0; byte* buffer2 = 0; byte* buffer3 = 0; byte* fat = 0; char dest[]="\\\\.\\F:"; char * possibleDestNameList[500] = {0}; char * fileNameList[500] = {0}; dword possibleDestPtrList[500] = {0}; dword filePtrList[1000] ={0}; dword upDR[100] = {0}; std::string command, moveTo, listingAtr, copy; char a = 0; char Letter ='F'; int depth = 0; int k = 0; int iter1 = 0; int num=0; int additionalshift = 0; dword bytesReturned = 0, fbufferSize = 0, fbufferSize2 = 0, sbufferSize = 0, max = 0, SC = 0, SPF = 0, TS = 0, RDO = 0, cDir = 0; long double forCeil = 0, SSA = 0, forFloor = 0; BootSector bs = {0}; ExtBootSector32 ebs32 = {0}; ExtBootSector ebs = {0}; std::cout<<"Enter the device letter:"; std::cin >> dest[4]; FILE * Disk = fopen(dest, "rb"); if(Disk == NULL) { std::cout << "Unable to open disk" << std::endl; return 1; } buffer = (byte *)malloc(100); fread( (char *)buffer, 100, 1, Disk); memcpy(&bs, buffer, sizeof(bs)); fbufferSize = bs.bpb.bpbBytesPerSector*bs.bpb.bpbSectorsPerTrack; buffer = (byte *)realloc(buffer, fbufferSize); _fseeki64( Disk, 0, SEEK_SET ); fread( (char *)buffer, fbufferSize, 1, Disk); TS = bs.bpb.bpbTotalSectors; if (TS == 0) TS = bs.bpb.bpbTotalSectorsBig; forCeil = (32*bs.bpb.bpbRootEntries)/bs.bpb.bpbBytesPerSector; SSA = bs.bpb.bpbReservedSectors+(bs.bpb.bpbNumberOfFATs*bs.bpb.bpbSectorsPerFAT)+/*ceil(forCeil)*/int(forCeil); SC = bs.bpb.bpbSectorsPerCluster; forFloor = (TS-SSA)/SC; max = 1 + dword(forFloor); if(max < 4085) { fat_type = 12; } else { if(max < 65525) { fat_type = 16; } else { fat_type = 32; } } std::cout << int (bs.bpb.bpbNumberOfFATs) << '\n'; if (fat_type==32) memcpy(&ebs32, buffer + sizeof(bs), sizeof(ebs32)); else memcpy(&ebs, buffer + sizeof(bs), sizeof(ebs)); if (fat_type == 12) { std::cout<<"Fat12 is not supported."<<std::endl; system("pause"); return -4; } if(fat_type == 32) { SPF = ebs32.bpb32SectorsPerFAT; sizeFat = 4; } else { SPF = bs.bpb.bpbSectorsPerFAT; sizeFat = 2; } free(buffer); RDO = bs.bpb.bpbReservedSectors * bs.bpb.bpbBytesPerSector + SPF * bs.bpb.bpbBytesPerSector * bs.bpb.bpbNumberOfFATs; fat = (byte *)malloc(SPF*bs.bpb.bpbBytesPerSector); _fseeki64( Disk, bs.bpb.bpbReservedSectors * bs.bpb.bpbBytesPerSector, SEEK_SET ); //Disk.seekg(bs.bpb.bpbReservedSectors * bs.bpb.bpbBytesPerSector, std::ios::beg); fread( (char *)fat, SPF*bs.bpb.bpbBytesPerSector, 1, Disk); //Disk.read((char *)fat, SPF*bs.bpb.bpbBytesPerSector); dword sizeofRead = bs.bpb.bpbBytesPerSector *bs.bpb.bpbSectorsPerCluster; dword sizeofFolderRead = sizeofRead; buffer2 = (byte *)malloc(sizeofRead); buffer3 = (byte *)malloc(sizeofRead); strncpy(currDir, RootDirName, strlen(RootDirName)+1); setlocale(LC_CTYPE, ""); dword clusterNum = 2; int FolderClusterCounter = 0; if(fat_type == 32) { while(clusterNum*sizeFat < SPF*bs.bpb.bpbBytesPerSector) { sizeofFolderRead = (FolderClusterCounter+1)*sizeofRead; buffer2 = (byte *)realloc(buffer2, sizeofFolderRead); _fseeki64( Disk, RDO + (clusterNum-2) * sizeofRead, SEEK_SET ); fread( (char *)buffer2+FolderClusterCounter*sizeofRead, sizeofRead, 1, Disk); clusterNum = getNext(fat, clusterNum); FolderClusterCounter++; } } else { sizeofFolderRead = bs.bpb.bpbRootEntries*32; buffer2 = (byte *)realloc(buffer2, sizeofFolderRead); _fseeki64( Disk, RDO, SEEK_SET ); fread( (char *)buffer2, sizeofFolderRead, 1, Disk); } getDirContent(buffer2, possibleDestNameList, possibleDestPtrList, fileNameList, filePtrList, 0); show_Console(); while(true) { std::cin>>command; if(!command.compare("cls")) { system("cls"); show_Console(); } if(!command.compare("ls")) { char c = getchar(); std::cout<<(int)c<<std::endl; if (c==' '){ clearAll(possibleDestNameList, fileNameList, possibleDestPtrList, filePtrList); std::cin>>listingAtr; show_Console(); free(buffer2); buffer2 = 0; FolderClusterCounter = 0; clusterNum = cDir+2; while(clusterNum*sizeFat < SPF*bs.bpb.bpbBytesPerSector) { if(fat_type == 16&& depth ==0) sizeofFolderRead = bs.bpb.bpbRootEntries*sizeof(DirectoryEntry); else sizeofFolderRead = (FolderClusterCounter+1)*sizeofRead; buffer2 = (byte *)realloc(buffer2, sizeofFolderRead); if(fat_type == 32) _fseeki64( Disk, RDO + (clusterNum-2) * sizeofRead, SEEK_SET ); else if(depth!=0) _fseeki64( Disk, RDO + bs.bpb.bpbRootEntries*sizeof(DirectoryEntry) + (clusterNum-2) * sizeofRead, SEEK_SET ); else _fseeki64( Disk, RDO, SEEK_SET ); if(fat_type == 16 && depth ==0) { fread( (char *)buffer2, sizeofFolderRead, 1, Disk); break; } else fread( (char *)buffer2+FolderClusterCounter*sizeofRead, sizeofRead, 1, Disk); clusterNum = getNext(fat, clusterNum); FolderClusterCounter++; } if(!listingAtr.compare("-s")) { getDirContent(buffer2+additionalshift, possibleDestNameList, possibleDestPtrList, fileNameList, filePtrList, 1); showDirectoryContent(possibleDestNameList, fileNameList, depth); continue; } if(!listingAtr.compare("-ct")) { getDirContent(buffer2+additionalshift, possibleDestNameList, possibleDestPtrList, fileNameList, filePtrList, 2); showDirectoryContent(possibleDestNameList, fileNameList, depth); continue; } if(!listingAtr.compare("-mt")) { getDirContent(buffer2+additionalshift, possibleDestNameList, possibleDestPtrList, fileNameList, filePtrList, 3); showDirectoryContent(possibleDestNameList, fileNameList, depth); continue; } if(!listingAtr.compare("help")) { show_Console(); std::cout<<"\n\"ls\" shows files in the current directory.\n\"ls -s\" print size of files.\n\"ls -ct\" print creation time of files.\n\"ls -mt\" print last modification time of files.\n\n"; system("pause"); show_Console(); continue; } } clearAll(possibleDestNameList, fileNameList, possibleDestPtrList, filePtrList); show_Console(); free(buffer2); buffer2 = 0; FolderClusterCounter = 0; clusterNum = cDir+2; while(clusterNum*sizeFat < SPF*bs.bpb.bpbBytesPerSector) { if(fat_type == 16&& depth ==0) sizeofFolderRead = bs.bpb.bpbRootEntries*sizeof(DirectoryEntry); else sizeofFolderRead = (FolderClusterCounter+1)*sizeofRead; buffer2 = (byte *)realloc(buffer2, sizeofFolderRead); if(fat_type == 32) _fseeki64( Disk, RDO + (clusterNum-2) * sizeofRead, SEEK_SET ); else if(depth!=0) _fseeki64( Disk, RDO + bs.bpb.bpbRootEntries*sizeof(DirectoryEntry) + (clusterNum-2) * sizeofRead, SEEK_SET ); else _fseeki64( Disk, RDO, SEEK_SET ); if(fat_type == 16 && depth ==0) { fread( (char *)buffer2,sizeofFolderRead, 1, Disk); break; } else fread( (char *)buffer2+FolderClusterCounter*sizeofRead, sizeofRead, 1, Disk); clusterNum = getNext(fat, clusterNum); FolderClusterCounter++; } getDirContent(buffer2+additionalshift, possibleDestNameList, possibleDestPtrList, fileNameList, filePtrList, 0); showDirectoryContent(possibleDestNameList, fileNameList, depth); } if(!command.compare("q")) break; if(!command.compare("cd")) { char c = getchar(); getline(std::cin, moveTo, '\n'); setlocale(LC_CTYPE, ""); decode(const_cast<char *>(moveTo.c_str())); lower(moveTo); if(!moveTo.compare("help")) { show_Console(); std::cout<<"\n\"cd \\\" will move you to root directory.\n\"cd ..\" will move you up one directory.\n\"cd $subfolder$\" will move you in a subdirectory called $subfolder$.\n\n"; system("pause"); show_Console(); } if(!moveTo.compare("\\")) { for(int i = depth; i>0; i--) { upDR[i]=0; } additionalshift=0; depth = 0; strncpy(currDir, RootDirName, strlen(RootDirName) +1); cDir = 0; free(buffer2); buffer2 = 0; FolderClusterCounter = 0; clusterNum = cDir+2; if(fat_type == 32) { while(clusterNum*sizeFat < SPF*bs.bpb.bpbBytesPerSector) { sizeofFolderRead = (FolderClusterCounter+1)*sizeofRead; buffer2 = (byte *)realloc(buffer2, sizeofFolderRead); _fseeki64( Disk, RDO + (clusterNum-2) * sizeofRead, SEEK_SET ); fread( (char *)buffer2+FolderClusterCounter*sizeofRead, sizeofRead, 1, Disk); clusterNum = getNext(fat, clusterNum); FolderClusterCounter++; } } else { sizeofFolderRead = bs.bpb.bpbRootEntries*32; buffer2 = (byte *)realloc(buffer2, sizeofFolderRead); _fseeki64( Disk, RDO, SEEK_SET ); fread( (char *)buffer2, sizeofFolderRead, 1, Disk); } upDR[depth] = 0; clearAll(possibleDestNameList, fileNameList, possibleDestPtrList, filePtrList); getDirContent(buffer2, possibleDestNameList, possibleDestPtrList, fileNameList, filePtrList, 0); show_Console(); } int k = 0; while(possibleDestNameList[k]){ std::string s (possibleDestNameList[k]); lower(s); if(!moveTo.compare(s)) { depth++; upDR[depth-1] = cDir; strncat(currDir, possibleDestNameList[k], 400); strncat(currDir, "\\", 400); cDir = possibleDestPtrList[k]; additionalshift = 2*sizeof(DirectoryEntry); free(buffer2); buffer2 = 0; FolderClusterCounter = 0; clusterNum = cDir+2; while(clusterNum*sizeFat < SPF*bs.bpb.bpbBytesPerSector) { if(fat_type == 16&& depth ==0) sizeofFolderRead = bs.bpb.bpbRootEntries*sizeof(DirectoryEntry); else sizeofFolderRead = (FolderClusterCounter+1)*sizeofRead; buffer2 = (byte *)realloc(buffer2, sizeofFolderRead); if(fat_type == 32) _fseeki64( Disk, RDO + (clusterNum-2) * sizeofRead, SEEK_SET ); else if(depth!=0) _fseeki64( Disk, RDO + bs.bpb.bpbRootEntries*sizeof(DirectoryEntry) + (clusterNum-2) * sizeofRead, SEEK_SET ); else _fseeki64( Disk, RDO, SEEK_SET ); if(fat_type == 16 && depth ==0) { fread((char *)buffer2, sizeofFolderRead, 1, Disk); break; } else fread( (char *)buffer2+FolderClusterCounter*sizeofRead, sizeofRead, 1, Disk); clusterNum = getNext(fat, clusterNum); FolderClusterCounter++; } clearAll(possibleDestNameList, fileNameList, possibleDestPtrList, filePtrList); getDirContent(buffer2+additionalshift, possibleDestNameList, possibleDestPtrList, fileNameList, filePtrList, 0); show_Console(); break; } k++; } if(!moveTo.compare("..")) { if(depth>0) depth--; int iter = 0; if(depth==0) additionalshift = 0; int countSlash = 0; while(currDir[iter]) { if((currDir[iter])=='\\') countSlash++; if(countSlash==(depth+2)) { currDir[iter+1] = 0; break; } iter++; } cDir = upDR[depth]; clearAll(possibleDestNameList, fileNameList, possibleDestPtrList, filePtrList); free(buffer2); buffer2 = 0; FolderClusterCounter = 0; clusterNum = cDir+2; while(clusterNum*sizeFat < SPF*bs.bpb.bpbBytesPerSector) { if(fat_type == 16&& depth ==0) sizeofFolderRead = bs.bpb.bpbRootEntries*sizeof(DirectoryEntry); else sizeofFolderRead = (FolderClusterCounter+1)*sizeofRead; buffer2 = (byte *)realloc(buffer2, sizeofFolderRead); if(fat_type == 32) _fseeki64( Disk, RDO + (clusterNum-2) * sizeofRead, SEEK_SET ); else if(depth!=0) _fseeki64( Disk, RDO + bs.bpb.bpbRootEntries*sizeof(DirectoryEntry) + (clusterNum-2) * sizeofRead, SEEK_SET ); else _fseeki64( Disk, RDO, SEEK_SET ); if(fat_type == 16 && depth ==0) { fread( (char *)buffer2, sizeofFolderRead, 1, Disk); break; } else fread( (char *)buffer2+FolderClusterCounter*sizeofRead, sizeofRead, 1, Disk); clusterNum = getNext(fat, clusterNum); FolderClusterCounter++; } getDirContent(buffer2+additionalshift, possibleDestNameList, possibleDestPtrList, fileNameList, filePtrList, 0); show_Console(); } } if(!command.compare("cp")) { char c = getchar(); getline(std::cin, copy, '\n'); setlocale(LC_CTYPE, ""); decode(const_cast<char *>(copy.c_str())); lower(copy); int k = 0; clearAll(possibleDestNameList, fileNameList, possibleDestPtrList, filePtrList); free(buffer2); buffer2 = 0; FolderClusterCounter = 0; clusterNum = cDir+2; while(clusterNum*sizeFat < SPF*bs.bpb.bpbBytesPerSector) { if(fat_type == 16&& depth ==0) sizeofFolderRead = bs.bpb.bpbRootEntries*sizeof(DirectoryEntry); else sizeofFolderRead = (FolderClusterCounter+1)*sizeofRead; buffer2 = (byte *)realloc(buffer2, sizeofFolderRead); if(fat_type == 32) _fseeki64( Disk, RDO + (clusterNum-2) * sizeofRead, SEEK_SET ); else if(depth!=0) _fseeki64( Disk, RDO + bs.bpb.bpbRootEntries*sizeof(DirectoryEntry) + (clusterNum-2) * sizeofRead, SEEK_SET ); else _fseeki64( Disk, RDO, SEEK_SET ); if(fat_type == 16 && depth ==0) { fread( (char *)buffer2, sizeofFolderRead, 1, Disk); break; } else fread( (char *)buffer2+FolderClusterCounter*sizeofRead, sizeofRead, 1, Disk); clusterNum = getNext(fat, clusterNum); FolderClusterCounter++; } getDirContent(buffer2+additionalshift, possibleDestNameList, possibleDestPtrList, fileNameList, filePtrList, 0); while(fileNameList[k]) { std::string s (fileNameList[k]); lower(s); if(!copy.compare(s)) { std::ofstream fileCopy (fileNameList[k], std::ios::out | std::ios::binary); dword fileOffset = 0; dword sizeofWrite = sizeofRead; if (sizeofWrite>filePtrList[k+500]) sizeofWrite=filePtrList[k+500]; if(fat_type==16) fileOffset = bs.bpb.bpbRootEntries*sizeof(DirectoryEntry) + filePtrList[k]*bs.bpb.bpbSectorsPerCluster*bs.bpb.bpbBytesPerSector; else fileOffset = filePtrList[k]*bs.bpb.bpbSectorsPerCluster*bs.bpb.bpbBytesPerSector; _fseeki64( Disk, RDO + fileOffset, SEEK_SET ); fread( (char*)buffer3, sizeofRead, 1, Disk); if(fileCopy.is_open()) fileCopy.write((char *)buffer3 ,sizeofWrite); word addressLow = 0; word addressHigh = 0; dword address = 0; dword numWrite = 2; dword numClast = filePtrList[k]+2; while(sizeofRead*numWrite < filePtrList[k+500]) { if(fat_type==16) memcpy(&addressLow, fat+sizeFat*numClast, 2); else { memcpy(&addressLow, fat+sizeFat*numClast, 2); memcpy(&addressHigh, fat+sizeFat*numClast+2, 1); } address = (addressLow | (addressHigh << 16))-2; if(fat_type==16) fileOffset = bs.bpb.bpbRootEntries*sizeof(DirectoryEntry) + address*bs.bpb.bpbSectorsPerCluster*bs.bpb.bpbBytesPerSector; else fileOffset = address*bs.bpb.bpbSectorsPerCluster*bs.bpb.bpbBytesPerSector; _fseeki64( Disk, RDO + fileOffset, SEEK_SET ); fread( (char*)buffer3, sizeofRead, 1, Disk); if(fileCopy.is_open()) fileCopy.write((char *)buffer3 ,sizeofWrite); numWrite++; numClast = address + 2; } if(filePtrList[k+500]>sizeofRead*(numWrite-1)) { if(fat_type==16) memcpy(&addressLow, fat+sizeFat*numClast, 2); else { memcpy(&addressLow, fat+sizeFat*numClast, 2); memcpy(&addressHigh, fat+sizeFat*numClast+2, 2); } address = (addressLow | (addressHigh << 16))-2; if(fat_type==16) fileOffset = bs.bpb.bpbRootEntries*sizeof(DirectoryEntry) + address*bs.bpb.bpbSectorsPerCluster*bs.bpb.bpbBytesPerSector; else fileOffset = address*bs.bpb.bpbSectorsPerCluster*bs.bpb.bpbBytesPerSector; _fseeki64( Disk, RDO + fileOffset, SEEK_SET ); fread( (char*)buffer3, sizeofRead, 1, Disk); if(fileCopy.is_open()) fileCopy.write((char *)buffer3 ,filePtrList[k+500]-sizeofWrite*(numWrite-1)); } break; } k++; } show_Console(); } } fclose(Disk); free(buffer2); free(buffer3); free(fat); return 0; } | ||||||
|
// Header.h // FAT #include <sstream> #include <locale> typedef unsigned short word; typedef unsigned char byte; typedef unsigned long dword; char fat_type = 0, sizeFat = 0; char RootDirName[100] = {0}; char currDir[2000] = {0}; char lfndName[400]={0}; struct DateTime { unsigned Year, Month, Day; unsigned Hour, Minute, Second; }; struct DirectoryEntry { char FileName[8]; char Extension[3]; enum {ReadOnly=0x1, Hidden=0x2, System=0x4, Volume=0x8, Directory=0x10}; byte attribute; byte reserved0; byte CreationTime10Milliseconds; word CreationTime, CreationDate; word AccessDate; word Node_high; word UpdateTime, UpdateDate; word Node_low; dword FileSize; bool IsAtEnd() const; bool IsDeleted() const; bool IsLFN() const; bool IsDirectory() const; DateTime GetCreationDate() const; DateTime GetLastAccessDate() const; DateTime GetLastModificationDate() const; }; DateTime UnpackDateTime(word date, word time) { DateTime d; d.Year =(date>>9) + 1980; d.Month=(date>>5) & 0xF; d.Day = date & 0x1F; d.Hour =(time>>11); d.Minute=(time>>5)& 0x3F; d.Second=(time & 0x1F)*2; return d; } struct BPB { word bpbBytesPerSector; byte bpbSectorsPerCluster; word bpbReservedSectors; byte bpbNumberOfFATs; word bpbRootEntries; word bpbTotalSectors; byte bpbMedia; word bpbSectorsPerFAT; word bpbSectorsPerTrack; word bpbHeadsPerCylinder; dword bpbHiddenSectors; dword bpbTotalSectorsBig; }; struct BootSector { byte bsJmp[3]; byte bsOemName[8]; BPB bpb; }; struct ExtBootSector { byte bsDriveNumber, bsUnused, bsExtBootSignature; dword bsSerialNumber; byte bsVolumeLabel[11]; byte bsFileSystem[8]; }; struct ExtBootSector32 { dword bpb32SectorsPerFAT; word bpb32Flags; word bpb32Version; dword bpb32RootCluster; word bpb32InfoSector; word bpb32BootBackupStart; byte bpb32Reserved[12]; ExtBootSector ebs16; }; struct LFNDirectoryEntry { byte seqNum; byte name1[10]; byte attribute; byte type; byte checksum; byte name2[12]; word firstCluster; byte name3[4]; }; void showDirectoryContent(char ** possibleDestNameList, char** fileNameList, int depth) { int i = 0; while(possibleDestNameList[i]) { std::cout<<possibleDestNameList[i]<<"\\"<<std::endl; i++; } i = 0; while(fileNameList[i]) { std::cout<<fileNameList[i]<<std::endl; i++; } } void DrowLine(int len){for(int i = 0; i<len; i++ ){putchar('-');}} void show_Console() { system("cls"); word Width = 80; DrowLine(Width); std::cout<<"Commands:"<<std::endl; std::cout<<" cls - Clear screen.\n ls - List files in current directory. \"ls help\" for info.\n cd - Change directory. \"cd help\" for info.\n \"cp $file$\" - Copy file to folder of the app.\n exit | quit | q - Close.\n"; DrowLine(Width); std::cout<<currDir; std::cout<<std::endl; DrowLine(Width); } void utf16ToASCII(int iter, char* lfndName, int numberOfLFND, word first, word last, char shift) { if(last==0) lfndName[13*(numberOfLFND-1)+shift+iter] = (int)first; else { if(last==0x04) { if(first == 1) lfndName[13*(numberOfLFND-1)+shift+iter] = -88; if(first == 0x51) lfndName[13*(numberOfLFND-1)+shift+iter] = -72; if(first< 0x30 && first> 0xf) lfndName[13*(numberOfLFND-1)+shift+iter] = -64+(first-0x10); if(first< 0x50 && first> 0x2f) lfndName[13*(numberOfLFND-1)+shift+iter] = -32+(first-0x30); } } } void getDirContent(byte* Dir, char ** possibleDestNameList, dword * possibleDestPtrList, char** fileNameList, dword * filePtrList, char sz) { int num = 0, posD = 0, posF = 0, cleanbuf = 0; char ff = 0; DirectoryEntry sfn= {0}; memcpy(&sfn, Dir, sizeof(sfn)); while(!sfn.IsAtEnd()) { int j = 0; int k = 0; std::string sizeOfFile, date, time, date2, time2; std::stringstream Buf, Buf2, Buf3, Buf4, Buf5; if(sfn.IsLFN()) { ff = 0; LFNDirectoryEntry lfnd; lfnd = reinterpret_cast<const LFNDirectoryEntry&>(sfn); word numberOfLFND = lfnd.seqNum & 0xF; while(numberOfLFND!=1) { for(int iter = 0;iter<5;iter++) utf16ToASCII(iter, lfndName, numberOfLFND, lfnd.name1[2*iter], lfnd.name1[2*iter+1], 0); for(int iter = 0;iter<6;iter++) utf16ToASCII(iter, lfndName, numberOfLFND, lfnd.name2[2*iter], lfnd.name2[2*iter+1], 5); for(int iter = 0;iter<2;iter++) utf16ToASCII(iter, lfndName, numberOfLFND, lfnd.name3[2*iter], lfnd.name3[2*iter+1], 11); num++; memcpy(&lfnd, Dir+num*sizeof(sfn), sizeof(sfn)); numberOfLFND = lfnd.seqNum & 0xF; } for(int iter = 0;iter<5;iter++) utf16ToASCII(iter, lfndName, numberOfLFND, lfnd.name1[2*iter], lfnd.name1[2*iter+1], 0); for(int iter = 0;iter<6;iter++) utf16ToASCII(iter, lfndName, numberOfLFND, lfnd.name2[2*iter], lfnd.name2[2*iter+1], 5); for(int iter = 0;iter<2;iter++) utf16ToASCII(iter, lfndName, numberOfLFND, lfnd.name3[2*iter], lfnd.name3[2*iter+1], 11); num++; memcpy(&sfn, Dir+num*sizeof(sfn), sizeof(sfn)); j = strlen(lfndName); word nodeH = 0; if(fat_type == 32) nodeH = sfn.Node_high; dword ofst = (dword)((sfn.Node_low | (nodeH << 16)))-2; if(sfn.IsDirectory()) { possibleDestPtrList[posD] = ofst; possibleDestNameList[posD] = (char *)realloc(possibleDestNameList[posD], j+10); memcpy(possibleDestNameList[posD], lfndName, j+1); posD++; }else { filePtrList[posF]=ofst; filePtrList[posF+500]=sfn.FileSize; fileNameList[posF] = (char *)realloc(fileNameList[posF], j+10); memcpy(fileNameList[posF], lfndName, j+1); posF++; Buf << sfn.FileSize; Buf >> sizeOfFile; Buf2 << sfn.GetCreationDate().Day<<"."<<sfn.GetCreationDate().Month<<"."<<sfn.GetCreationDate().Year; Buf2 >> date; Buf3 << sfn.GetCreationDate().Hour<<":"<<sfn.GetCreationDate().Minute<<":"<<sfn.GetCreationDate().Second; Buf3 >> time; Buf4 << sfn.GetLastModificationDate().Day<<"."<<sfn.GetLastModificationDate().Month<<"."<<sfn.GetLastModificationDate().Year; Buf4 >> date2; Buf5 << sfn.GetLastModificationDate().Hour<<":"<<sfn.GetLastModificationDate().Minute<<":"<<sfn.GetLastModificationDate().Second; Buf5 >> time2; j--; ff = 1; } cleanbuf = 0; while(lfndName[cleanbuf]) { lfndName[cleanbuf] = 0; cleanbuf++; } } else { ff = 0; if(!sfn.IsDeleted() && (sfn.attribute!=sfn.Volume)) { for(int i = 0; i < 8; i++) if(sfn.FileName[i]==' ') { j = i; break; } else { if(sfn.FileName[i] >= 'A' && sfn.FileName[i] <= 'Z') sfn.FileName[i] = sfn.FileName[i]+'a'-'A'; if(i == 7) j = 8; } word nodeH = 0; if(fat_type == 32) nodeH = sfn.Node_high; dword ofst = (dword)((sfn.Node_low | (nodeH << 16))-2); if(sfn.IsDirectory()) { possibleDestPtrList[posD] = ofst; possibleDestNameList[posD] = (char *)realloc(possibleDestNameList[posD], j+5); memcpy(possibleDestNameList[posD], sfn.FileName, j); memcpy(possibleDestNameList[posD]+j, "\0", 1); posD++; ff=0; } else { filePtrList[posF] = ofst; filePtrList[posF+500] = sfn.FileSize; for(int i = 0; i < 4; i++) if(sfn.Extension[i]==' ') { k = i; break; } else { if(sfn.Extension[i] >= 'A' && sfn.Extension[i] <= 'Z') sfn.Extension[i] = sfn.Extension[i]+'a'-'A'; } fileNameList[posF] = (char *)realloc(fileNameList[posF], j+5); memcpy(fileNameList[posF],sfn.FileName, j); if(k!= 0) { memcpy(fileNameList[posF]+j, ".", 1); memcpy(fileNameList[posF]+j+1, sfn.Extension, k); memcpy(fileNameList[posF]+j+k+1,"\0", 1); } else memcpy(fileNameList[posF]+j,"\0", 1); posF++; Buf << sfn.FileSize; Buf >> sizeOfFile; Buf2 << sfn.GetCreationDate().Day<<"."<<sfn.GetCreationDate().Month<<"."<<sfn.GetCreationDate().Year; Buf2 >> date; Buf3 << sfn.GetCreationDate().Hour<<":"<<sfn.GetCreationDate().Minute<<":"<<sfn.GetCreationDate().Second; Buf3 >> time; Buf4 << sfn.GetLastModificationDate().Day<<"."<<sfn.GetLastModificationDate().Month<<"."<<sfn.GetLastModificationDate().Year; Buf4 >> date2; Buf5 << sfn.GetLastModificationDate().Hour<<":"<<sfn.GetLastModificationDate().Minute<<":"<<sfn.GetLastModificationDate().Second; Buf5 >> time2; ff = 1; } } } if (sz!=0 && posF>0 && ff==1) { int i = j+k+1; if (k==0) i = j; fileNameList[posF -1] = (char *)realloc(fileNameList[posF -1], i+5); memcpy(fileNameList[posF -1]+i, " ", 2); i = i+2; switch(sz) { case 1: fileNameList[posF -1] = (char *)realloc(fileNameList[posF -1], i+sizeOfFile.size()+5); memcpy(fileNameList[posF -1]+i, sizeOfFile.c_str(), sizeOfFile.size()+1); break; case 2: fileNameList[posF -1] = (char *)realloc(fileNameList[posF -1], i+date.size()+time.size()+5); memcpy(fileNameList[posF -1]+i, date.c_str(), date.size()); memcpy(fileNameList[posF -1]+i+date.size(), " ", 1); memcpy(fileNameList[posF -1]+i+date.size() +1 , time.c_str(), time.size()+1); break; case 3: fileNameList[posF -1] = (char *)realloc(fileNameList[posF-1], i+date2.size()+time2.size()+5); memcpy(fileNameList[posF -1]+i, date2.c_str(), date2.size()); memcpy(fileNameList[posF -1]+i+date2.size(), " ", 1); memcpy(fileNameList[posF -1]+i+date2.size() +1 , time2.c_str(), time2.size()+1); break; } } num++; memcpy(&sfn, Dir+num*sizeof(sfn), sizeof(sfn)); } } void clearAll(char ** possibleDestNameList, char ** fileNameList, dword * possibleDestPtrList, dword * filePtrList) { int i = 0; while(possibleDestNameList[i]) { free(possibleDestNameList[i]); possibleDestNameList[i] = 0; possibleDestPtrList[i] = 0; i++; } i = 0; while(fileNameList[i]) { free(fileNameList[i]); fileNameList[i] = 0; filePtrList[i] = 0; filePtrList[i+500] = 0; i++; } } void decode(char * str) { for(word iter=0; iter<strlen(str);iter++) { if(str[iter]<0) { if(str[iter]==-15) { str[iter]=-72; continue; } if(str[iter]==-16) { str[iter]=-88; continue; } if(str[iter]>=-32 && str[iter]<=-17) { str[iter]=-16 + (32+str[iter]); continue; } if(str[iter]>=-96 && str[iter]<=-81) { str[iter]=-32 + (96+str[iter]); continue; } if(str[iter]>=-128 && str[iter]<=-97) { str[iter]=-64 + (128+str[iter]); continue; } } } } dword getNext(byte* fat , dword clusterNum) { word Low = 0, High = 0; if(fat_type == 16) memcpy(&Low, fat+sizeFat*clusterNum, 2); else { memcpy(&Low, fat+sizeFat*clusterNum, 2); memcpy(&High, fat+sizeFat*clusterNum+2, 1); } clusterNum = (Low | (High << 16)); return clusterNum; } void lower(std::string& s) { std::locale loc (""); std::string::iterator i = s.begin(); std::string::iterator end = s.end(); while (i != end) { *i = std::tolower(*i, loc); i++; } } | ||||||
|
это звиздец полный - выкладывать в форуме всю программу в нескольких сообщениях Опасайтесь багов в приведенном выше коде; я только доказал корректность, но не запускал его. — Donald E. Knuth. | ||||||
Перейти в раздел:
© 2004 - 2024, Delphi.int.ru |
Версия форума: 1.10 (19.01.2010) |
Выполнено за 0.26 сек. |