📄 kmfs.c
字号:
DWORD i;
DWORD dwRetv = NULL_SECTOR;
//CheckFat(lpVol);
if( dwAllocSector == NULL_SECTOR ) //
{ // 等同于 AllocSector
return AllocSector( lpVol, nSectorNum );
}
else if( nSectorNum == 0 )
{ // 等同于释放 free all block
FreeSector( lpVol, dwAllocSector );
return NULL_SECTOR;
}
else
{
DWORD s = dwAllocSector;
DWORD p = dwAllocSector;
DWORD * pfat;
i = 0;
EnterCriticalSection( &lpVol->csFat );// 进入冲突段
pfat = lpVol->lpdwFat;
while( s != NULL_SECTOR )
{
i++;
if( i > nSectorNum )
{ // 减少扇区,释放一些。decrease sector, to free other sector
DEBUGMSG(FILE_ZONE, (TEXT("ReallocSector: RealocSector decrease\r\n")));
*(pfat+p) = NULL_SECTOR;
lpVol->dwMaxNeedUpdate = MAX( lpVol->dwMaxNeedUpdate, p );
lpVol->dwMinNeedUpdate = MIN( lpVol->dwMinNeedUpdate, p );
lpVol->fUpdate = 1;
FreeSector( lpVol, s );
dwRetv = dwAllocSector;
goto _RETV;
}
p = s;
s = NEXT_SECTOR( pfat, s );
}
if( i < nSectorNum ) // < or == ?
{ // 小于,额外分配一些
s = AllocSector( lpVol, (nSectorNum - i) );
if( s != NULL_SECTOR )
{
*(pfat+p) = s; // 连接在一起。link them
// 需要更新的FAT域
lpVol->dwMaxNeedUpdate = MAX( lpVol->dwMaxNeedUpdate, p );
lpVol->dwMinNeedUpdate = MIN( lpVol->dwMinNeedUpdate, p );
lpVol->fUpdate = 1;
DEBUGMSG(FILE_ZONE, (TEXT("ReallocSector: RealocSector crease success\r\n")));
dwRetv = dwAllocSector;
goto _RETV;
}
else
{
WARNMSG(FILE_ZONE, (TEXT("ReallocSector: RealocSector failure!.\r\n")));
dwRetv = NULL_SECTOR;
goto _RETV;
}
}
else if( i == nSectorNum )
{ // 等于, 不需要做什么
dwRetv = dwAllocSector;
goto _RETV;
}
_RETV:
LeaveCriticalSection( &lpVol->csFat );// 离开冲突段
}
return dwRetv;
}
// **************************************************
// 声明:static DWORD LinkSector( LPKFSDVOL lpVol, DWORD dwDest, DWORD dwSource )
// 参数:
// IN lpVol - 卷对象指针
// IN dwDest - 目标扇区
// IN dwSource - 源扇区
// 返回值:
// 假如成功,返回非NULL_SECTOR值;否则,返回NULL_SECTOR
// 功能描述:
// 将两个扇区链表连接起来
// 引用:
// **************************************************
static DWORD LinkSector( LPKFSDVOL lpVol, DWORD dwDest, DWORD dwSource )
{
DWORD dwSector = dwDest;
//CheckFat(lpVol);
EnterCriticalSection( &lpVol->csFat );// 离开冲突段
ASSERT( dwDest != NULL_SECTOR && dwSource != NULL_SECTOR );
// 找到目标尾
while( *(lpVol->lpdwFat+dwSector) != NULL_SECTOR )
dwSector = *(lpVol->lpdwFat+dwSector);
// 连接,dest + source
*(lpVol->lpdwFat+dwSector) = dwSource;
// 需要更新的系统数据区
lpVol->dwMaxNeedUpdate = MAX( lpVol->dwMaxNeedUpdate, dwSector );
lpVol->dwMinNeedUpdate = MIN( lpVol->dwMinNeedUpdate, dwSector );
lpVol->fUpdate = 1;
LeaveCriticalSection( &lpVol->csFat );// 离开冲突段
return dwDest;
}
// **************************************************
// 声明:static DWORD GetSectorOffset( LPKFSDVOL lpVol, DWORD dwStartSector, UINT nOffset )
// 参数:
// IN lpVol - 卷对象指针
// IN dwStartSector - 开始扇区
// IN nOffset - 从开始扇区起的偏移数
// 返回值:
// 假如成功,返回非NULL_SECTOR的扇区索引; 否则,返回NULL_SECTOR
// 功能描述:
// 得到从给定的扇区链表起的第nOffset个扇区索引
// 引用:
// **************************************************
static DWORD GetSectorOffset( LPKFSDVOL lpVol, DWORD dwStartSector, UINT nOffset )
{
DWORD * pfat = lpVol->lpdwFat;
EnterCriticalSection( &lpVol->csFat );
while( dwStartSector != NULL_SECTOR && nOffset )
{
dwStartSector = NEXT_SECTOR( pfat, dwStartSector );
nOffset--;
}
LeaveCriticalSection( &lpVol->csFat );
return dwStartSector;
}
// **************************************************
// 声明:static DWORD GetSectorNum( LPKFSDVOL lpVol, DWORD dwStartSector )
// 参数:
// IN lpVol - 卷对象指针
// IN dwStartSector - 开始扇区
// 返回值:
// 扇区数
// 功能描述:
// 得到从开始扇区起的扇区数
// 引用:
// **************************************************
static DWORD GetSectorNum( LPKFSDVOL lpVol, DWORD dwStartSector )
{
DWORD * pfat = lpVol->lpdwFat;
DWORD i = 0;
EnterCriticalSection( &lpVol->csFat );
while( dwStartSector != NULL_SECTOR )
{
dwStartSector = NEXT_SECTOR( pfat, dwStartSector );
i++;
}
LeaveCriticalSection( &lpVol->csFat );
return i;
}
// **************************************************
// 声明:static BOOL ReallocFile( LPKFSDFILE lpFile, DWORD dwSize )
// 参数:
// IN lpFile - 打开文件对象结构指针
// IN dwSize - 文件长度
// 返回值:
// 假如成功,返回TRUE; 否则, 返回FALSE
// 功能描述:
// 重新设定文件大小
// 引用:
// **************************************************
static BOOL ReallocFile( LPKFSDFILE lpFile, DWORD dwSize )
{
DWORD dwStartSector;
if( dwSize != GET_NODE_PTR(lpFile)->nFileLength ) // 是否与当前文件的大小相等 ?
{ // 不相等,重分配
dwStartSector = ReallocSector( lpFile->lpVol,
GET_NODE_PTR(lpFile)->dwStartSector,
( (dwSize + lpFile->lpVol->fdd.nBytesPerSector - 1) / lpFile->lpVol->fdd.nBytesPerSector ) );
//
if( dwStartSector != NULL_SECTOR || dwSize == 0 )
{ // 更新数据
GET_NODE_PTR(lpFile)->dwStartSector = dwStartSector;
GET_NODE_PTR(lpFile)->nFileLength = dwSize;
}
else
return FALSE;
}
return TRUE;
}
// **************************************************
// 声明:static int GetFolderAdr( LPTSTR * lppFolder, LPCTSTR lpcfn, int * lpNextLen )
// 参数:
// OUT lppFolder - 用于接收文件夹名的缓存
// IN lpcfn - 文件路径名
// OUT lpNextLen - 用于接收下一个文件名的相对位置
// 返回值:
// 功能描述:
// 引用:
// **************************************************
static int GetFolderAdr( LPTSTR * lppFolder, LPCTSTR lpcfn, int * lpNextLen )
{
int i = 0;
int fn = 0;
if( IS_NAME_BREAK(*lpcfn) ) // 是名字分割符("\" or "/")吗?
{ // 是
lpcfn++; ///parent level
i++;
}
while( *lpcfn && fn < MAX_FILE_NAME_LEN )
{ // 将所有非分割符拷贝到缓存
if( !IS_NAME_BREAK(*lpcfn) )
{
if( fn == 0 )
*lppFolder = (LPTSTR)lpcfn;
lpcfn++;
i++; fn++;
}
else
break;
}
*lpNextLen = i;
return fn;
}
// 文件夹操作码
#define OP_DEL 0x0001 // (OP_DELFILE | OP_DELFOLDER)
#define OP_ADD 0x0004 // add node if not found, the lpFile->node is valid
#define OP_UPDATE 0x0008 // update node, the lpFile->node is valid
#define OP_GET 0x0010 // get node, fill lpFile->node
// **************************************************
// 声明:static BOOL DoFolderInit(
// LPKFSDVOL lpVol ,
// DWORD dwFolderSector,
// DWORD dwParentSector,
// WORD * pSector )
// 参数:
// IN lpVol - 卷对象结构指针
// IN dwFolderSector - 当前文件夹数据所在扇区
// IN dwParentSector - 当前文件夹的上一级文件夹数据所在扇区
// IN/OUT pSector - 一个扇区大小的当前文件夹内存
// 返回值:
// 假如成功,返回TRUE; 否则, 返回FALSE
// 功能描述:
// 初始化新的文件夹数据。将新的文件夹数据写入pSector内存并将其写入磁盘
// 引用:
// **************************************************
static BOOL DoFolderInit(
LPKFSDVOL lpVol ,
DWORD dwFolderSector,
DWORD dwParentSector,
WORD * pSector )
{
PNODE pNode = (PNODE)pSector;
// 清0
memset( pSector, 0, lpVol->fdd.nBytesPerSector );
// 每一个文件夹的第一个文件节点表示自己
// 第二个文件节点表示上级文件夹/父文件夹
// 初始化自身。init this folder
pNode->bFlag = NODE_MARK;
pNode->strName[0] = '.'; // 自身标示
pNode->dwStartSector = dwFolderSector; // 指向自身开始扇区
pNode->bNameLen = 1;
pNode->wAttrib |= FILE_ATTRIBUTE_DIRECTORY;
pNode->wAttrib |= FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
// 初始化父文件夹 init parent folder
pNode = (PNODE)( (LPBYTE)pSector + NODE_ALIGN_SIZE );
pNode->bFlag = NODE_MARK;
pNode->strName[0] = '.';// 父文件夹标示 ".."
pNode->strName[1] = '.';// 父文件夹标示
pNode->bNameLen = 2;
pNode->dwStartSector = dwParentSector; // 指向父文件夹开始扇区
pNode->wAttrib |= FILE_ATTRIBUTE_DIRECTORY;
pNode->wAttrib |= FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
// 写入磁盘
if( ERROR_SUCCESS == FSDMGR_WriteDisk( lpVol->hDsk, dwFolderSector, 1, (LPBYTE)pSector, lpVol->fdd.nBytesPerSector ) )
return TRUE;
return FALSE;
}
// **************************************************
// 声明:static BOOL SearchFolder( SF * psf, BOOL bNext, int nStartIndex )
// 参数:
// IN psf - SF结构指针
// IN bNext - 是否从下一个文件节点开始查找/比较(假如为TRUE,则nStartIndex无效)
// IN nStartIndex - 开始查找/比较的文件节点索引号(假如bNext为FALSE,则nStartIndex有效)
// 返回值:
// 假如找到匹配的文件名,返回TRUE; 否则, 返回FALSE
// 功能描述:
// 查找匹配的文件
// 引用:
// **************************************************
extern BOOL FileNameCompare( LPCTSTR lpcszMask, int iMaskLen, LPCTSTR lpcszSrc, int iSrcLen );
static BOOL SearchFolder( SF * psf, BOOL bNext, int nStartIndex )
{
LPCTSTR lpcszFileName = psf->lpszCurName; // 需要查找的文件名(可以含有通配符)
int iFileNameLen = psf->dwCurNameLen; // 查找的文件名长度
PNODE lpNode;
UINT uiCurNodeNum = 0;
UINT uiCurNodeIndex;
UINT uiSectorOffset;
DWORD dwCurSector;
DWORD dwOffset;
DWORD nBytesPerSector = psf->lpVol->fdd.nBytesPerSector;
BOOL bUpdate, bRetv = FALSE;
if( bNext )
{ // 如果向下查找,将当前查找节点索引设为下一个文件节点
// search next file match with filename
uiCurNodeIndex = psf->nCurNodeIndex + psf->nCurNodeNum;
}
else
{ // 从文件夹的开始查找
uiCurNodeIndex = nStartIndex;
psf->dwAddNodeSector = NULL_SECTOR;
psf->nEmptyNodeIndex = -1;
psf->nDelNodeIndex = -1;
}
// uiCurNodeIndex数据在第几个扇区
uiSectorOffset = uiCurNodeIndex / psf->lpVol->nNodesPerSector;
// uiCurNodeIndex数据所在扇区索引
dwCurSector = GetSectorOffset( psf->lpVol, psf->dwFolderStartSector, uiSectorOffset );
// uiCurNodeIndex数据在扇区内偏移
dwOffset = ( (uiCurNodeIndex * NODE_ALIGN_SIZE) % nBytesPerSector );
bUpdate = TRUE;
EnterCriticalSection( &psf->lpVol->csNode );
// 读节点数据/查找
while( dwCurSector != NULL_SECTOR )
{
// search node in sector
if( bUpdate )
{ // 读取扇区数据到 psf->pSector
if( FSDMGR_ReadDisk( psf->lpVol->hDsk, dwCurSector, 1, psf->pSector, psf->lpVol->fdd.nBytesPerSector ) != ERROR_SUCCESS )
break;
}
// 每个扇区包含若干索引节点
lpNode = (PNODE)( (LPBYTE)psf->pSector + dwOffset );
if( lpNode->bFlag == NODE_EMPTY ||
lpNode->bFlag == NODE_DELETED )
{ // 该节点为空或已被删除的
if( lpNode->bFlag == NODE_EMPTY )
{ // 空节点,设定psf结构的 无效节点成员数据
if( psf->dwAddNodeSector == NULL_SECTOR )
{
psf->nEmptyNodeIndex = uiCurNodeIndex;
psf->dwAddNodeSector = dwCurSector;
psf->nFreeNodeNum = psf->lpVol->nNodesPerSector - uiCurNodeIndex % psf->lpVol->nNodesPerSector;
}
goto RETV; // 不需要再查找
}
else
{ // // 被删除节点,设定psf结构的 删除节点成员数据 deleted node
if( psf->dwAddNodeSector == NULL_SECTOR &&
lpNode->bNameLen >= psf->dwCurNameLen )
{
psf->nDelNodeIndex = uiCurNodeIndex;
psf->dwAddNodeSector = dwCurSector;
psf->nFreeNodeNum = GET_NODE_NUM( lpNode );
}
}
// 得到当前文件节点的节点数
uiCurNodeNum = GET_NODE_NUM( lpNode );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -