6
c读取ext2表和位图信息
source link: https://blog.popkx.com/c-read-ext2-tables-and-bitmap-information/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
本节根据前面几讲介绍的 ext2 的数据结构,建立了几个结构体,用于存储 ext2 的各种表和位图信息。
为了读写方便,在 MFile 模块添加了如下几个函数。
unsigned char MFileReadByte(off_t liFrom)
{
unsigned char rtn = 0;
if(-1 == MFileRead(&rtn, 1, liFrom)){
printf("%s read error, Message: %s\n", __FUNCTION__, strerror(errno));
return MFILE_READ;
}
return rtn;
}
int MFileWriteByte(off_t liFrom, unsigned char ucWriteData)
{
if(-1 == MFileWrite(liFrom, &ucWriteData, 1)){
printf("%s write error, Message: %s\n", __FUNCTION__, strerror(errno));
return MFILE_WRITE;
}
return MFILE_OK;
}
// 将 2 字节的整数拆分成 2 个 1字节的整数,并且按照小端顺序写入地址 liFrom
int MFileWriteUint16InByte(off_t liFrom, uint16 data)
{
uint8 tmp = 0;
tmp = (uint8)(data&0xff);
MFileWriteByte(liFrom, tmp);
tmp = (uint8)(data>>8);
MFileWriteByte(liFrom+1, tmp);
return MFILE_OK;
}
// 将 4 字节的整数拆分成 4 个 1字节的整数,并且按照小端顺序写入地址 liFrom
int MFileWriteUint32InByte(off_t liFrom, uint32 data)
{
uint8 tmp = 0;
tmp = (uint8)(data&0xff);
MFileWriteByte(liFrom, tmp);
tmp = (uint8)((data>>8)&0xff);
MFileWriteByte(liFrom+1, tmp);
tmp = (uint8)((data>>16)&0xff);
MFileWriteByte(liFrom+2, tmp);
tmp = (uint8)((data>>24)&0xff);
MFileWriteByte(liFrom+3, tmp);
return MFILE_OK;
}
int MFileWriteStringInByte(off_t liFrom, char* str)
{
uint32 i = 0;
while('\0' != *(str+i)){
MFileWriteByte(liFrom+i, *(str+i));
i++;
}
return MFILE_OK;
}
// 读 4 字节,因为读到的是小端,所以要转换下
uint32 MFileRead4Byte(off_t liFrom)
{
uint32 tmp = 0;
uint32 rtn = 0;
tmp = (uint32)MFileReadByte(liFrom);
rtn |= tmp;
tmp = (uint32)MFileReadByte(liFrom+1);
rtn |= tmp<<8;
tmp = (uint32)MFileReadByte(liFrom+2);
rtn |= tmp<<16;
tmp = (uint32)MFileReadByte(liFrom+3);
rtn |= tmp<<24;
return rtn;
}
// 读 2 字节,因为读到的是小端,所以要转换下
uint16 MFileRead2Byte(off_t liFrom)
{
uint16 tmp = 0;
uint16 rtn = 0;
tmp = (uint16)MFileReadByte(liFrom);
rtn |= tmp;
tmp = (uint16)MFileReadByte(liFrom+1);
rtn |= tmp<<8;
return rtn;
}
新建 MExt2 模块
MExt2.h
#include "../include/MFile.h"
// Bm -> Bitmap
// Loc -> Location
// dir -> directories
#define MEXT2_OK 0
#define MEXT2_INIT -1
#define MEXT2_INFO -2
#define MEXT2_IDLEBITMAP -3
#define MEXT2_IDLEINODEBLOCK -4
// 块组描述符表
typedef struct{
uint32 blockBmLoc;
uint32 inodeBmLoc;
uint32 inodeTable;
uint16 freeBlocks;
uint16 freeInodes;
uint16 directories;
} sGroupDescriptor;
// inode 表
typedef struct{
uint16 st_mode;
uint16 user;
uint32 size;
uint32 atime;
uint32 ctime;
uint32 mtime;
uint32 dtime;
uint16 group;
uint16 links;
uint32 ocupiedBlocks;
uint32 flags;
uint32 osInfo;
uint32 blocks[15];
} sInode;
// 数据块
typedef struct{
uint32 inodeIndex;
uint16 recordLen;
uint8 fileNameLen;
uint8 fileType;
uint8 fileName[256]; // malloc 根据 fileNameLen
}sDataBlock;
// super block
typedef struct
{
uint32 inodes;
uint32 blocks;
uint32 reservedBlocks;
uint32 freeBlocks;
uint32 freeInodes;
uint32 firstBlock;
uint32 blockSize; // 1024<<blockSize = 实际块大小(Bytes)
uint32 log; // 给 0 就成
uint32 blocksPerGroup;
uint32 framsPerGroup;
uint32 inodesPerGroup;
uint32 lastMountTime;
uint32 lastWriteTime;
uint16 mountNum;
uint16 maxMountNum;
uint16 magic;
uint16 fsState;
uint16 errBehav;
uint16 minorRev;
uint32 lastCheck;
uint32 checkIntvl;
uint32 osType;
uint32 majorRev;
uint16 reserverdBlocksUid;
uint16 reserverdBlocksGid;
uint32 firstInode;
uint16 inodeSize;
uint16 blockGroupIndex;
uint8 compatibleFeatures[12];
uint8 uuid[16];
uint8 volmName[16];
// 余下的填充零
} sSuperBlock;
MExt2.c
#include "../include/MExt2.h"
static char m_fileName[255] = {0};
static sSuperBlock s_sprBlk;
static sGroupDescriptor s_grpDescrpt;
static int sGetSuperBlockInfo(sSuperBlock* pSuperBlock);
static int sGetGroupDescriptorInfo(sGroupDescriptor* pGrpDescrpt);
int InitMExt2(char* cpFileName)
{
if(0 > MFileOpen(cpFileName)){
printf("InitMExt2 error, MFileOpen failed\n");
return MEXT2_INIT;
}
sGetSuperBlockInfo(&s_sprBlk);
sGetGroupDescriptorInfo(&s_grpDescrpt);
return MEXT2_OK;
}
// 未加错误判断
// 超级块,占一个块
static int sGetSuperBlockInfo(sSuperBlock* pSuperBlock)
{
pSuperBlock->inodes = MFileRead4Byte(0x400);
pSuperBlock->blocks = MFileRead4Byte(0x400 + 4);
pSuperBlock->reservedBlocks = MFileRead4Byte(0x400 + 4*2);
pSuperBlock->freeBlocks = MFileRead4Byte(0x400 + 4*3);
pSuperBlock->freeInodes = MFileRead4Byte(0x400 + 4*4);
pSuperBlock->firstBlock = MFileRead4Byte(0x400 + 4*5);
pSuperBlock->blockSize = 1024<<MFileRead4Byte(0x400 + 4*6);
pSuperBlock->blocksPerGroup = MFileRead4Byte(0x420);
pSuperBlock->framsPerGroup = MFileRead4Byte(0x420 + 4);
pSuperBlock->inodesPerGroup = MFileRead4Byte(0x420 + 4*2);
pSuperBlock->inodeSize = MFileRead2Byte(0x458);
pSuperBlock->blockGroupIndex = MFileRead2Byte(0x458 + 2);
return MEXT2_OK;
}
int GetSuperBlockInfo(sSuperBlock* pSuperBlock)
{
*pSuperBlock = s_sprBlk;
return MEXT2_OK;
}
// 未完美错误判断
// 块组
static int sGetGroupDescriptorInfo(sGroupDescriptor* pGrpDescrpt)
{
uint32 start = 0;
// 首先获取起点,即超级块结束的位置
start = 0x400 + 1024;
pGrpDescrpt->blockBmLoc = MFileRead4Byte(start);
pGrpDescrpt->inodeBmLoc = MFileRead4Byte(start + 4);
pGrpDescrpt->inodeTable = MFileRead4Byte(start + 4*2);
pGrpDescrpt->freeBlocks = MFileRead2Byte(start + 4*3);
pGrpDescrpt->freeInodes = MFileRead2Byte(start + 4*3 + 2);
pGrpDescrpt->directories = MFileRead4Byte(start + 4*3 + 2*2);
return MEXT2_OK;
}
int GetGroupDescriptorInfo(sGroupDescriptor* pGrpDescrpt)
{
*pGrpDescrpt = s_grpDescrpt;
return MEXT2_OK;
}
// 获取 inode
int sGetInodeInfo(off_t addr, sInode* pSInode)
{
int i = 0;
pSInode->st_mode = MFileRead2Byte(addr);
pSInode->user = MFileRead2Byte(addr + 2*1);
pSInode->size = MFileRead4Byte(addr + 2*2);
pSInode->group = MFileRead2Byte(addr + 24);
pSInode->links = MFileRead2Byte(addr + 24 + 2);
pSInode->ocupiedBlocks = MFileRead4Byte(addr + 24 + 2*2 );
for(i=0; i<15; i++){
pSInode->blocks[i] = MFileRead4Byte(addr + 40 + 4*i);
}
return MEXT2_OK;
}
这里有函数名字前面有个 s,是因为计划将这些函数作为静态函数使用。目前为了开发调试方便,有的未加 static 关键字。
main.c
#include "../include/MExt2.h"
char fileName[] = "../../tmp/disk";
sSuperBlock sb;
sGroupDescriptor sg;
int main()
{
InitMExt2(fileName);
printf("GetSuperBlockInfo: ----------------------\n");
GetSuperBlockInfo(&sb);
printf("inodes: %ld\n", sb.inodes);
printf("blocks: %ld\n", sb.blocks);
printf("blockSize: %d\n", sb.blockSize);
printf("reservedBlocks: %ld\n", sb.reservedBlocks);
printf("freeBlocks: %ld\n", sb.freeBlocks);
printf("freeInodes: %ld\n", sb.freeInodes);
printf("firstBlock: %ld\n", sb.firstBlock);
printf("blocksPerGroup: %ld\n", sb.blocksPerGroup);
printf("framsPerGroup: %ld\n", sb.framsPerGroup);
printf("inodesPerGroup: %ld\n", sb.inodesPerGroup);
printf("inodeSize: %d\n", sb.inodeSize);
printf("blockGroupIndex: %d\n", sb.blockGroupIndex);
printf("GetGroupDescriptorInfo: ----------------------\n");
GetGroupDescriptorInfo(&sg);
printf("blockBmLoc: %d\n", sg.blockBmLoc);
printf("inodeBmLoc: %d\n", sg.inodeBmLoc);
printf("inodeTable: %d\n", sg.inodeTable);
printf("freeBlocks: %d\n", sg.freeBlocks);
printf("freeInodes: %d\n", sg.freeInodes);
printf("directories: %d\n", sg.directories);
return 0;
}
- 编译后,运行,结果如下:
$ ./main.out
GetSuperBlockInfo: ----------------------
inodes: 128
blocks: 1024
blockSize: 1024
reservedBlocks: 51
freeBlocks: 986
freeInodes: 117
firstBlock: 1
blocksPerGroup: 8192
framsPerGroup: 8192
inodesPerGroup: 128
inodeSize: 128
blockGroupIndex: 0
GetGroupDescriptorInfo: ----------------------
blockBmLoc: 6
inodeBmLoc: 7
inodeTable: 8
freeBlocks: 986
freeInodes: 117
directories: 2
- 这里以获取 超级块信息 和 块组描述符 为例,其他的表信息获取类似。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK