📄 kmfs.c
字号:
else if( lpNode->bFlag == NODE_MARK )
{ // 该文件节点已被使用
uiCurNodeNum = GET_NODE_NUM( lpNode );// 得到当前文件节点的节点数
if( uiCurNodeNum > 1 &&
(uiCurNodeNum * NODE_ALIGN_SIZE + dwOffset) > nBytesPerSector )
{
lpNode = psf->pCurNode;
if( 0 == ReadSectors( psf->lpVol, dwCurSector, dwOffset, (LPBYTE)lpNode, uiCurNodeNum * NODE_ALIGN_SIZE, psf->pSector, NULL ) )
goto RETV; // 读错误
}
if( lpcszFileName[0] == '.' )// 是否需要查找的是 '.' 或 '..' ?
{ // 是 '.' or '..' ?
if( (iFileNameLen == 1 && uiCurNodeIndex == 0) ||
(iFileNameLen == 2 && uiCurNodeIndex == 1) )
{ // yes, find it
bRetv = TRUE;
}
}
else // 不是,比较
bRetv = FileNameCompare( lpcszFileName, iFileNameLen, lpNode->strName, lpNode->bNameLen );
if( bRetv )
{ // 找到,设置psf结构相关成员
psf->nCurNodeIndex = uiCurNodeIndex;
psf->nCurNodeNum = uiCurNodeNum;
psf->dwCurNodeSector = dwCurSector;
memcpy( psf->pCurNode, lpNode, GET_NODE_SIZE( lpNode ) );
bRetv = TRUE;
goto RETV;
}
}
else
{
// error
ERRORMSG(FILE_ZONE, (TEXT("error in SearchFolder: find undef node flag(0x%x)!.\r\n"), lpNode->bFlag ));
goto RETV;
}
// 当前节点不符号,准备下一个文件节点。not find match name
uiCurNodeIndex += uiCurNodeNum;
{
UINT t = uiCurNodeIndex / psf->lpVol->nNodesPerSector;
bUpdate = uiSectorOffset < t; // 下一个节点是否在当前扇区 ?
for( ; uiSectorOffset < t && dwCurSector != NULL_SECTOR; uiSectorOffset++ )
{
dwCurSector = NEXT_SECTOR( psf->lpVol->lpdwFat, dwCurSector );
}
}
dwOffset = GET_NODE_OFFSET( uiCurNodeIndex, psf->lpVol );
}
RETV:
LeaveCriticalSection( &psf->lpVol->csNode ); // 离开冲突段
return bRetv;
}
// **************************************************
// 声明:static DWORD NewFolder( LPKFSDVOL lpVol, DWORD dwParent, void * lpSectorBuf )
// 参数:
// IN lpVol - 卷对象数据结构
// IN dwParent - 上级文件夹
// IN lpSectorBuf - 用于读取扇区数据的缓存
// 返回值:
// 假如成功,返回新文件夹的扇区索引号;失败,返回NULL_SECTOR
// 功能描述:
// 创建新的文件夹
// 引用:
// **************************************************
static DWORD NewFolder( LPKFSDVOL lpVol, DWORD dwParent, void * lpSectorBuf )
{
DWORD dwSector;
dwSector = AllocSector( lpVol, 1 ); // 为新文件夹分配扇区
if( dwSector != NULL_SECTOR )
{ // 分配成功,初始化新文件夹数据
if( DoFolderInit( lpVol , dwSector, dwParent, lpSectorBuf ) )
return dwSector;
else
{ // 失败
FreeSector( lpVol, dwSector );
}
}
return NULL_SECTOR;
}
// **************************************************
// 声明:static DWORD AddNodeSector( PSF psf, DWORD dwNeedSectors )
// 参数:
// IN psf - 查找结构指针
// IN dwNeedSectors - 需要的扇区数
// 返回值:
// 假如成功,返回非 NULL_SECTOR值;否则,返回扇区值
// 功能描述:
// 为新的节点增加存储扇区
// 引用:
// **************************************************
static DWORD AddNodeSector( PSF psf, DWORD dwNeedSectors )
{
DWORD dwNodeSector;
DEBUGMSG(FILE_ZONE, (TEXT("KFSD: DoNodeAdd, No Empty Node\r\n")));
dwNodeSector = AllocSector( psf->lpVol, dwNeedSectors );
if( dwNodeSector != NULL_SECTOR )
{ // 分配成功
DWORD dwInitSector;
memset( psf->pSector, 0, psf->lpVol->fdd.nBytesPerSector );
EnterCriticalSection( &psf->lpVol->csNode ); // 进入冲突段
// 连接到当前文件夹
LinkSector( psf->lpVol, psf->dwFolderStartSector, dwNodeSector );
// init it
dwInitSector = dwNodeSector;
// 将初始化数据写入磁盘
while( dwNeedSectors-- )
{
ASSERT_NOTIFY( dwInitSector != NULL_SECTOR, "error sector\r\n" );
if( FSDMGR_WriteDisk( psf->lpVol->hDsk, dwInitSector, 1, psf->pSector, psf->lpVol->fdd.nBytesPerSector ) != ERROR_SUCCESS )
{
dwNodeSector = NULL_SECTOR;
break;
}
dwInitSector = NEXT_SECTOR( psf->lpVol->lpdwFat, dwInitSector );
}
LeaveCriticalSection( &psf->lpVol->csNode ); // 离开冲突段
}
return dwNodeSector;
}
// **************************************************
// 声明:static BOOL DoNodeAdd( PSF psf, PNODE pNode )
// 参数:
// IN psf - 查找结构指针
// IN pNode - 文件节点
// 返回值:
// 假如成功,返回TRUE;否则,返回FALSE
// 功能描述:
// 在当前文件夹里增加一个文件节点
// 引用:
// **************************************************
static BOOL DoNodeAdd( PSF psf, PNODE pNode )
{
DWORD dwOffset;
DWORD dwNodeSector;
UINT uiNodeIndex;
DWORD dwNeedSectors;
DWORD dwNeedNodeNum;
UINT nBytesPerSector = psf->lpVol->fdd.nBytesPerSector;
DEBUGMSG(FILE_ZONE, (TEXT("KFSD: DoNodeAdd.\r\n")));
EnterCriticalSection( &psf->lpVol->csNode ); // 进入冲突段
if( (dwNodeSector = psf->dwAddNodeSector) == NULL_SECTOR )
{ // 当前文件夹没有空闲节点,增加。。alloc enough sector to save the node
DEBUGMSG(FILE_ZONE, (TEXT("KFSD: DoNodeAdd, No Empty Node\r\n")));
dwNeedSectors = ( GET_NODE_SIZE( pNode ) + nBytesPerSector - 1 ) / nBytesPerSector;
// 为文件夹分配新的磁盘扇区
dwNodeSector = AddNodeSector( psf, dwNeedSectors );
if( dwNodeSector != NULL_SECTOR )
{ //成功
dwOffset = 0;
uiNodeIndex = GetSectorNum( psf->lpVol, psf->dwFolderStartSector ) * psf->lpVol->nNodesPerSector;
}
else
{ // 失败
LeaveCriticalSection( &psf->lpVol->csNode );// 离开冲突段
return FALSE;
}
}
else
{ // 有空闲节点
dwNeedNodeNum = GET_NODE_NUM( pNode ); // 得到新文件节点所需节点数
if( psf->nDelNodeIndex != -1 )
{ // 空闲节点是删除节点
ASSERT( dwNeedNodeNum <= psf->nFreeNodeNum );
if( dwNeedNodeNum < psf->nFreeNodeNum )
{ // 节点数足够并且比需要的多,将余下节点的分离出去
NODE node;
DWORD dwFreeSector;
memset( &node, 0, sizeof( NODE ) );
// 为余下节点准备数据
node.bFlag = NODE_DELETED;
node.dwStartSector = NULL_SECTOR;
node.bNameLen = (BYTE)( (psf->nFreeNodeNum - dwNeedNodeNum) * NODE_ALIGN_SIZE - sizeof( NODE ) + NODE_RESERVE_NAME_LEN );
// 得到余下节点索引所在扇区。 get node index and offset to split
dwFreeSector = GetSectorOffset( psf->lpVol,
psf->dwFolderStartSector,
(psf->nDelNodeIndex + dwNeedNodeNum) / psf->lpVol->nNodesPerSector );
// 得到余下节点索引所在扇区内的偏移
dwOffset = GET_NODE_OFFSET( (psf->nDelNodeIndex + dwNeedNodeNum), psf->lpVol );
ASSERT( dwFreeSector != NULL_SECTOR );
// 写入磁盘
if( 0 == WriteSectors( psf->lpVol, dwFreeSector, dwOffset, (LPBYTE)&node, NODE_ALIGN_SIZE - NODE_RESERVE_NAME_LEN, psf->pSector ) )
{ // 失败
LeaveCriticalSection( &psf->lpVol->csNode );// 离开冲突段
return FALSE;//
}
}
// set node index and offset to added
// 新的文件节点的索引号 和 偏移
uiNodeIndex = psf->nDelNodeIndex;
dwOffset = GET_NODE_OFFSET( psf->nDelNodeIndex, psf->lpVol );
}
else
{ // 空索引节点 has empty index
ASSERT( psf->nEmptyNodeIndex != -1 );
if( psf->nFreeNodeNum < dwNeedNodeNum )
{ // 足够 add node sector
dwNeedSectors = ( (dwNeedNodeNum - psf->nFreeNodeNum) * NODE_ALIGN_SIZE + nBytesPerSector - 1 ) / nBytesPerSector;
if( AddNodeSector( psf, dwNeedSectors ) == NULL_SECTOR )
{ // 失败
LeaveCriticalSection( &psf->lpVol->csNode );// 离开冲突段
return FALSE;// no sector
}
}
// 新的文件节点的索引号 和 偏移
uiNodeIndex = psf->nEmptyNodeIndex;
dwOffset = GET_NODE_OFFSET( psf->nEmptyNodeIndex, psf->lpVol );
}
}
DEBUGMSG(FILE_ZONE, (TEXT("KFSD: DoNodeAdd, Sector=%d, Index=%d\r\n"), psf->dwAddNodeSector, psf->nEmptyNodeIndex));
pNode->bFlag = NODE_MARK; // 设置为占用标志
// 写入磁盘
if( ( dwOffset = WriteSectors( psf->lpVol, dwNodeSector, dwOffset, (LPBYTE)pNode, GET_NODE_SIZE( pNode ), psf->pSector ) ) )
{
psf->nCurNodeIndex = uiNodeIndex;
psf->dwCurNodeSector = dwNodeSector;
memcpy( psf->pCurNode, pNode, GET_NODE_SIZE(pNode) );
}
LeaveCriticalSection( &psf->lpVol->csNode );// 离开冲突段
return dwOffset != 0;
}
// **************************************************
// 声明:static BOOL DoNodeUpdate( PSF psf, PNODE pNode )
// 参数:
// IN psf - 查找结构指针
// IN pNode - 文件节点
// 返回值:
// 假如成功,返回TRUE;否则,返回FALSE
// 功能描述:
// 更新当前文件夹里一个文件节点
// 引用:
// **************************************************
static BOOL DoNodeUpdate( PSF psf, PNODE pNode )
{
BOOL bRetv;
DWORD dwOffset = GET_NODE_OFFSET( psf->nCurNodeIndex, psf->lpVol );
DEBUGMSG(FILE_ZONE, (TEXT("KFSD: DoNodeUpdate.\r\n")));
EnterCriticalSection( &psf->lpVol->csNode ); // 进入冲突段
// 写入磁盘
bRetv = WriteSectors( psf->lpVol, psf->dwCurNodeSector, dwOffset, (LPBYTE)pNode, GET_NODE_SIZE( pNode ), psf->pSector );
LeaveCriticalSection( &psf->lpVol->csNode ); // 离开冲突段
if( bRetv && psf->pCurNode != pNode )
memcpy( psf->pCurNode, pNode, GET_NODE_SIZE( pNode ) ); // 更新psf成员
return bRetv;
}
// **************************************************
// 声明:static BOOL DoNodeGet( PSF psf, PNODE pNode )
// 参数:
// IN psf - 查找结构指针
// IN pNode - 文件节点
// 返回值:
// 假如成功,返回TRUE;否则,返回FALSE
// 功能描述:
// 得到当前文件夹里一个文件节点的数据
// 引用:
// **************************************************
static BOOL DoNodeGet( PSF psf, PNODE pNode )
{
DWORD dwOffset = GET_NODE_OFFSET( psf->nCurNodeIndex, psf->lpVol );
DEBUGMSG(FILE_ZONE, (TEXT("KFSD: DoNodeGet\r\n")));
memcpy( pNode, psf->pCurNode, GET_NODE_SIZE( psf->pCurNode ) );
return TRUE;
}
// **************************************************
// 声明:static BOOL DoNodeDel( PSF psf, BOOL bFreeSector )
// 参数:
// IN psf - 查找结构指针
// IN bFreeSector - 需要释放扇区
// 返回值:
// 假如成功,返回TRUE;否则,返回FALSE
// 功能描述:
// 删除文件节点
// 引用:
// **************************************************
static BOOL DoNodeDel( PSF psf, BOOL bFreeSector )
{
DWORD dwOffset;
BOOL bRetv;
EnterCriticalSection( &psf->lpVol->csNode ); // 进入冲突段
if( bFreeSector )
{ // 释放扇区
if( psf->pCurNode->nFileLength ||
(psf->pCurNode->wAttrib & FILE_ATTRIBUTE_DIRECTORY) )
{
ASSERT( psf->pCurNode->dwStartSector != NULL_SECTOR );
if( psf->pCurNode->dwStartSector != NULL_SECTOR )
FreeSector( psf->lpVol, psf->pCurNode->dwStartSector ); // 释放文件节点的数据扇区
}
else
{
;//ASSERT( psf->pCurNode->wStartSector == NULL_SECTOR );
}
}
psf->pCurNode->bFlag = NODE_DELETED; // 设置删除标志
dwOffset = GET_NODE_OFFSET( psf->nCurNodeIndex, psf->lpVol );
// 将数据写到磁盘
bRetv = WriteSectors( psf->lpVol, psf->dwCurNodeSector, dwOffset, (LPBYTE)psf->pCurNode, GET_NODE_SIZE( psf->pCurNode ), psf->pSector );
LeaveCriticalSection( &psf->lpVol->csNode ); // 离开冲突段
return bRetv;
}
// **************************************************
// 声明:static BOOL DoFolderChange(
// SF * psf,
// PNODE pNode,
// int op )
// 参数:
// IN psf - 查找结构指针
// IN pNode - 文件节点结构
// IN op - 操作码
// 返回值:
// 假如成功,返回TRUE;否则,返回FALSE
// 功能描述:
// 对文件夹做相关操作
// 引用:
// **************************************************
static BOOL DoFolderChange(
SF * psf,
PNODE pNode,
int op )
{
DEBUGMSG(FILE_ZONE, (TEXT("KFSD: DoFolderChange.\r\n")));
switch( op )
{
case OP_DEL: // 删除文件夹
{
SF sfChild;
if( BeginSearch( &sfChild, psf->lpVol, psf->hProc, NULL ) ) // 初始化搜索结构数据
{ // 搜索当前文件夹里是否为空(有别的文件节点?)
sfChild.lpszCurName = "*";
sfChild.dwCurNameLen = 1;
sfChild.dwFolderStartSector = psf->pCurNode->dwStartSector;
op = SearchFolder( &sfChild, FALSE, USER_NODES ); // 搜索
EndSearch( &sfChild );
if( op ) // 有别的文件节点 ?
{ // 有,非空
SetLastError( ERROR_DIR_NOT_EMPTY );
return FALSE;
}
else
return DoNodeDel( psf, TRUE );// 2004-02-03
}
// 2004-02-03
// return DoNodeDel( psf, TRUE );
//
return FALSE;
}
break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -