Professional Documents
Culture Documents
Report
Report
HÀNH
HỆ ĐIỀU HÀNH
Quản lý hệ thống tập tin trên Windows
MỤC LỤC
NHÓM THỰC HIỆN..........................................................................................................................1
MỤC LỤC............................................................................................................................................2
BẢNG PHÂN CÔNG CÔNG VIỆC...................................................................................................3
ĐÁNH GIÁ MỨC ĐỘ HOÀN THÀNH.............................................................................................5
ĐỐI VỚI PHÂN VÙNG FAT32.........................................................................................................6
ĐỐI VỚI PHÂN VÙNG NTFS.........................................................................................................11
...................................................................................................................................................................
ĐỒ ÁN HỆ ĐIỀU
HÀNH
Đọc thông tin chi tiết trên phân vùng FAT32 100%
Đọc thông tin chi tiết trên phân vùng NTFS 100%
2. Trên cả đồ án:
- Đã hoàn thành tất cả yêu cầu đề đặt ra.
ĐỒ ÁN HỆ ĐIỀU
- bool kiemTra(BYTE sector[512]): Hàm đảm bảo tính liên tục của các entry,
kiểm tra entry tiếp theo có rỗng hay không.
4. Demo chương trình
- Link demo youtube : https://www.youtube.com/watch?v=fEh3nQ7abU4
- Ổ đĩa (D:) mới được tạo theo kiểu định dạng FAT32 và có các nội dung:
Hình 5: Cây thư mục Hình 6 : Các tệp con của tệp DOAN
Giải thích : Màn hình Console có xuất hiện 1 cặp mở -|> và đóng <|- có nghĩa
là đang mở thư mục con của một tệp đang là thư mục cha, và nội dung của tệp
định dạng txt được xuất ra.
Một số lưu ý:
- Một số câu hỏi: các câu hỏi mà nhóm thực hành báo cáo gặp phải khi bắt đầu
thực hiện đồ án và câu trả lời cho các vấn đề nhóm đã tìm hiểu và trao đổi với
nhau. Đây là cơ sở để có thể cài đặt các hàm.
- Struct: các struct lưu trữ dữ liệu của các thành phần chính của một ổ đĩa. Lưu
ý,struct chỉ chứa các thông tin cần thiết để thực hiện yêu cầu đồ án, không
phải lưu trữ tất cả thông tin.
- Các hàm chính: điểm qua một số hàm chính và công dụng của nó. Lưu ý, các
bước chi tiết hàm sẽ thực hiện sẽ được chú thích trong Source code ở các file
cpp.
- Mô tả quá trình debug: điểm qua từng bước chương trình sẽ chạy khi Debug.
Ngoài ra trong Source code mà nhóm nộp đồ án, trong các file.h sẽ chú thích
mô tả chức năng của các hàm và file.cpp sẽ chú thích cách hàm triển khai.
Đầu tiên, ta xác định MFT entry là tệp tin hay thư mục, bằng cách nhìn vào
MFT entry header ở offset 0x16 (2 byte), đây là giá trị cờ báo: 0x01 là tệp tin được
cấp phát, 0x02 là thư mục bị xóa, 0x03 là thư mục được cấp phát, 0x04 và 0x08 là
không xác dịnh. Sau đó, mã ID định danh của một MFT entry là số thứ tự của nó
trong vùng MFT. Ví dụ $MFT có ID là 0, MFT entry tiếp sau nó có mã ID là 1 và
cứ thế tiếp tục. Trong phần nội dung của attribute FILENAME, 8 byte đầu giữ địa
chỉ ID của MFT entry thư mục cha.
Vậy để tạo cây thư mục, MFT entry cần giữ: trạng thái là tệp tin hay thư mục,
mã ID, mã ID của thư mục cha.
17 MFT entry đầu của một ổ đĩa luôn xác định, thư mục gốc sẽ luôn mang ID là 5.
Từ MFT entry 18 trở đi sẽ là của tệp tin và các thư mục khác.
Atrribute BITMAP chỉ có ở MFT entry đầu tiên là $MFT, ở đây lưu trữ dữ
liệu một dãy nhị phân cho biết MFT entry nào đang được sử dụng theo thứ tự
ngược lại. VD: 1010 thì MFT entry ở vị trí 1 và 3 được sử dụng. Dựa vào tiền đề
này, ta lấy chỉ số MFT entry lớn nhất được sử dụng, đó là chỉ số của bit 1 cuối
cùng của dãy nhị phân trên. Và khi đọc MFT, ta chạy vòng lặp từ 0 đến chỉ số đó
để đọc các MFT entry.
Trên thực tế, Atrribute BITMAP chỉ lưu trữ địa chỉ dãy nhị phân trên, nội
dung nằm ở vùng Non-resident. Ta phải đọc được vị trí đó bằng một chỉ số đặc
biệt gọi là DataRun. (Thường ở vị trí offset 40h bắt đầu từ đầu Attribute, số lượng
bytes đọc tùy theo chỉ số DataRun quy định).
31 01 1 0 1 0 0 0 0 0 0 0
Byte đầu 31 sẽ thể hiện tổng số byte phải đọc, số cluster mà vùng dữ liệu đó
chiếm và cluster bắt đầu.
ĐỒ ÁN HỆ ĐIỀU
Byte thấp (1): cho chúng ta biết cần phải đọc 1 byte sau byte đầu để lấy Số
cluster cần phải đọc. Ở đây là 01h byte, tức là vùng dữ liệu non-resident cần đọc
chiếm 1 cluster.
Byte cao (3): cho chúng ta biết cần phải đọc 3 byte sau byte đầu với số byte
mà byte thấp yêu cầu đọc, trường hợp này, ta bỏ qua 2 byte (1 byte đầu + 1 byte).
Ở đây là 010041h, tức vùng dữ liệu non-resident bắt đầu từ Cluster thứ 65601, từ
đó ta đổi sang sector.
Vậy tổng cộng chúng ta đọc 5 byte (1 + 1 + 3) ở offset 40h. Các byte 00 phía
sau chứng tỏ đã hết DataRun để đọc.
1.3. Đọc data non-resident
Nếu nội dung của tệp tin lớn, cụ thể vượt quá 700 byte thì Atrribute Data sẽ
không giữ nội dung tệp tin mà sẽ lưu trữ địa chỉ nội dung sẽ được lưu ở cluster
nào, chiếm bao nhiêu cluster ở vùng Non-resident. Và dấu hiệu kết thúc nội dung
là 0xFFFF. Ta phải đọc được vị trí đó bằng một chỉ số đặc biệt gọi là DataRun.
//Struct giữ các chỉ số quan trọng của Bios Parameter Block (BPB)
struct BPB
{
int bytePerSector; //Số byte cho 1 sector
int sectorPerCluster; //Số sector cho 1 cluster
int sectorPerTrack; //Số sector cho 1 track
int numHead; //Số head
int64 numSectorOfDisk; //Số sector của ổ đĩa
};
//Struct giữ vị trí bắt đầu và kết thúc của vùng Master File Table (MFT)
struct MFT
{
int startClusterMFT; //Cluster bắt đầu MFT
ĐỒ ÁN HỆ ĐIỀU
//Struct lưu giữ dữ liệu ở Attribute Data của một MFT entry
struct AttributeData
{
string content;
};
// Attribute Bitmap lưu trữ chuỗi mã nhị phân cho biết entry nào được sử dụng,
chỉ có ở $MFT
struct AttributeBitmap
{
int magicNumber;
};
{
int id;//ID của MFT entry
int64 idSector; //sector bắt đầu MFT entry
int type; //0: tập tin đã xóa, 1: tập tin được cấp phát, 2: thư mục đã xóa,
3: thư mục được cấp phát
BYTE sector1[512]; //nửa entry đầu
BYTE sector2[512]; //nửa entry cuối
vector<Attribute> attributes; //danh sách các Attribute
vector< int64> sectors; //các sector mà data được lưu trữ
};
//Struct tệp tin, các thông tin cơ bản được lấy từ các attribute của mft entry
tương ứng
struct File
{
int id;
string name;
int size;//Kích thước
string data;
int parentIndex;//ID cha
vector< int64> sectors; //các sector lưu trữ
};
//Struct thư mục, các thông tin cơ bản được lấy từ các attribute của mft entry
tương ứng
struct Folder
{
int id;
string name;
vector<File> child;//tệp tin con
vector<Folder> folderchild;//thư mục con
int parentIndex;
vector< int64> sectors; //các sector lưu trữ
};
4. Hàm đã thực hiện
Đây là các hàm phụ để giúp đọc các chỉ số của các struct. Ở đây, chia làm hai
phần là ReadSector và ReadByte.
ĐỒ ÁN HỆ ĐIỀU
Cụ thể chức năng từng hàm đã được chú thích trong Source code ở
ReadSector.h và ReadByte.h
a. MFT
Trong đó, để xác định chỉ số MFT cuối cùng (đã đề cập ở câu hỏi 3, phần Mở
đầu) ta gọi hàm int GetLastMFTEntry(MFTEntry entry).
c. Atrribute
- Hàm đọc các danh sách các attribute của MFT entry, ở đây ta chú ý đến 3
atrribute FILENAME, DATA, BITMAP (Chỉ có ở $MFT)
vector<Attribute> ReadAttributes(MFTEntry mftentry, int startAttr,
LPCWSTR drive)
Hàm sẽ thực hiện một vòng lặp, mỗi lần lặp đọc 1 atrribute đến khi hết.
Ở đây, chúng ta sẽ bàn về điều kiện hủy vòng lặp
while (startAttr + attribute.size < 1024)
{
…
…
…
startAttr += attribute.size; //Điểm bắt đầu của attribute tiếp theo bằng
tổng điểm bắt đầu và chiều dài của attribute hiện tại
ĐỒ ÁN HỆ ĐIỀU
- Gọi hàm ReadMFT(mft, bpb, sector, drive); Trong đó, để lấy chỉ số MFT entry
cuối cùng thì gọi hàm int GetLastMFTEntry(MFTEntry entry) ở magicNumber
struct AttributeBitmap.
- Lặp vòng lặp từ MFT entry đầu tiên đến chỉ số MFT cuối cùng để gọi hàm
ReadMFTEntry(entry, mft.startClusterMFT * bpb.sectorPerCluster, i, drive);
- Mỗi MFT entry sẽ đọc header để biết tệp tin hay thư mục và đọc vị trí của
atrribute đầu tiên. Sau đó đọc lần lượt các attribute của mình vào
vector<Attribute>. Nếu là FILENAME thì sẽ lưu tên của tệp tin/thư mục và
mã ID của cha; DATA thì đọc nội dung, tùy theo resident hay non-resident mà
đọc ở vùng MFT hay vùng Non-resdident; BITMAP chỉ có ở $MFT và nội
dung được lưu ở vùng Non-resident.
- Sau đó, thực hiện hàm PrintRootFolder(entries, files, folders) để đọc các MFT
entry vào tệp tin, thư mục và in ra cây thư mục.
ĐỒ ÁN HỆ ĐIỀU
- Ta thấy được ở thư mục gốc có thư mục A, tệp tin New Text Document.txt,
DataGeneration1.sql.
- Sau đó người dùng có thể chọn truy xuất tiếp tệp tin hay thư mục bằng
cách chọn 0 hay 1.
ĐỒ ÁN HỆ ĐIỀU
- Người dùng tiếp tục nhập ID tệp tin hay thư mục để hiển thị nội dung bên
trong.
- Kết thúc khi nhấn ESC.
5. Demo chương trình
Link youtube: https://youtu.be/1_u2YS6PdZM
6. Tài liệu tham khảo
- Slide bài giảng Hệ Điều Hành Thạc Sĩ Lê Viết Long ĐH KHTN – TPHCM
- https://sabercomlogica.com/en/ntfs-non-resident-and-no-named-attributes/
- Chuỗi bài blog Hệ thống tệp tin NTFS của thầy Lê Gia Công:
https://legiacong.blogspot.com/2014/04/he-thong-quan-ly-tap-tin-ntfs-4-vbr-
bpb.html