⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kmfs.c

📁 深圳市微逻辑电子有限公司 巨果&#8226 Kingmos&reg 系统核心
💻 C
📖 第 1 页 / 共 5 页
字号:
    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 + -