📄 kmfs.c
字号:
case OP_ADD: // 增加文件夹
// 分配新的文件夹数据结构
pNode->dwStartSector = NewFolder( psf->lpVol, psf->dwFolderStartSector, psf->pSector );
if( pNode->dwStartSector != NULL_SECTOR )
return DoNodeAdd( psf, pNode ); // 写入磁盘节点
else
return FALSE;
}
return FALSE;
}
// **************************************************
// 声明:static BOOL SearchNode( SF * lpsf )
// 参数:
// IN lpsf - 查找结构指针
// 返回值:
// 假如成功,返回TRUE;否则,返回FALSE
// 功能描述:
// 查找文件节点
// 引用:
// **************************************************
static BOOL SearchNode(
SF * lpsf )
{
int len;
LPTSTR lpszName;
BOOL bRetv = FALSE;
DEBUGMSG(FILE_ZONE, (TEXT("KFSD: SearchNode From Folder=%d.\r\n"), lpsf->lpVol->rfh.dwDataStartSector));
EnterCriticalSection( &lpsf->lpVol->csNode );
lpsf->dwFolderStartSector = lpsf->lpVol->rfh.dwDataStartSector;
lpszName = lpsf->lpszName; // 文件路径名
lpsf->dwCurNameLen = 0; //
lpsf->lpszCurName = NULL;
while( 1 )
{
int iNextLen;
LPTSTR lpszCurName;
// 从lpszName得到其文件/路径名
// example : "\\kingmos\\folder1\\folder2\\folder3\\filename.txt"
// 1filename 2fn 3fn 4fn 5fn
// lpszCurName指向当前得到的文件名(不含'\'),iNextLen为下一个文件名在lpszName的位置
len = GetFolderAdr( &lpszCurName, lpszName, &iNextLen );
if( len ) // 得到吗 ?
{ //是,准备查找结构
lpsf->nCurNodeIndex = 0;
lpsf->lpszCurName = lpszCurName; // 需要查找的文件节点名
lpsf->dwCurNameLen = len; // // 需要查找的文件节点名长度
lpszName += iNextLen; // 指向下一个名
if( SearchFolder( lpsf, FALSE, ALL_NODES ) ) // 查找
{ // 发现它 find node
if( *lpszName ) // 还有文件夹吗 ?
{ // 是,如果当前查找到的是文件夹,则继续 the node must is folder
if( lpsf->pCurNode->wAttrib & FILE_ATTRIBUTE_DIRECTORY ) // the node is folder
{ // 文件夹
lpsf->dwFolderStartSector = lpsf->pCurNode->dwStartSector;
continue; // continue search in sub folder
}
else
{ // 非文件夹 not folder
DEBUGMSG(FILE_ZONE, (TEXT("KFSD: Node is'nt folder=%s.\r\n"), lpsf->lpszCurName));
}
}
else
{ // 找到
DEBUGMSG(FILE_ZONE, (TEXT("KFSD: Find Node=%s.\r\n"), lpsf->pCurNode->strName));
bRetv = TRUE;
break;
}
}
else
{ // 没有找到
DEBUGMSG(FILE_ZONE, (TEXT("KFSD: not find folder=%s.\r\n"), lpsf->lpszCurName ));
}
}
break;
}
LeaveCriticalSection( &lpsf->lpVol->csNode ); // 离开冲突段
if( bRetv )
SetLastError(ERROR_FILE_EXISTS);
else
SetLastError(ERROR_FILE_NOT_FOUND);
return bRetv;
}
// **************************************************
// 声明:static BOOL BeginSearch( SF * lpsf, LPKFSDVOL lpVol, HANDLE hProc, LPTSTR lpszName )
// 参数:
// IN lpsf - 查找结构指针
// IN lpVol - 卷对象结构指针
// IN hProc - 拥有者进程句柄
// IN lpszName - 需要查找的文件路径名
// 返回值:
// 假如成功,返回TRUE;否则,返回FALSE
// 功能描述:
// 初始化一个查找对象结构
// 引用:
// **************************************************
static BOOL BeginSearch( SF * lpsf, LPKFSDVOL lpVol, HANDLE hProc, LPTSTR lpszName )
{ // 为读写磁盘扇区准备缓存
lpsf->pSector = malloc( MAX_NODE_BYTES + lpVol->fdd.nBytesPerSector );
if( lpsf->pSector )
{ // 初始化查找对象结构
lpsf->pCurNode = (PNODE)( ((LPBYTE)lpsf->pSector) + lpVol->fdd.nBytesPerSector );//MAX_NODE_BYTES;
lpsf->lpVol = lpVol;
lpsf->hProc = hProc;
lpsf->lpszName = lpszName;
memset( lpsf->pCurNode, 0, MAX_NODE_BYTES );
return TRUE;
}
return FALSE;
}
// **************************************************
// 声明:static void EndSearch( SF * lpsf )
// 参数:
// IN lpsf - 查找结构指针
// 返回值:
// 无
// 功能描述:
// 与BeginSearch相反,释放搜索数据
// 引用:
// **************************************************
static void EndSearch( SF * lpsf )
{
if( lpsf->pSector )
free( lpsf->pSector );
}
// **************************************************
// 声明:static DWORD ReadSectors(
// LPKFSDVOL lpVol,
// DWORD dwStartSector,
// DWORD nOffset,
// LPBYTE lpBuf,
// DWORD dwSize,
// LPBYTE pSector,
// UINT * lpCacheValid )
// 参数:
// IN lpVol - 卷对象结构指针
// IN dwStartSector - 开始扇区
// IN nOffset - 在扇区内偏移字节
// IN lpBuf - 用于接受数据的缓存
// IN dwSize - 需要接受的数据
// IN pSector - 用于读取扇区数据的临时缓存
// IN lpCacheValid - 用于接收整个扇区数据是否有效
// 返回值:
// 读取的数据大小
// 功能描述:
// 读取扇区的数据,将实际需要的数据写入lpBuf,并返回实际读取的数据大小
// 引用:
//
// **************************************************
static DWORD ReadSectors( LPKFSDVOL lpVol, DWORD dwStartSector,
DWORD nOffset, LPBYTE lpBuf, DWORD dwSize,
LPBYTE pSector,
UINT * lpCacheValid )
{
DWORD nSectorSize = lpVol->fdd.nBytesPerSector;
DWORD s = dwSize;
BOOL bCache = FALSE;
//RETAILMSG(FILE_ZONE, (TEXT("KFSD: ReadSector, Sector=%d, nOffset=%d, Size=%d\r\n"), wStartSector, nOffset, dwSize));
ASSERT_NOTIFY( dwStartSector != NULL_SECTOR, "no valid sector number\r\n" );
if( dwStartSector != NULL_SECTOR )
{
if( dwSize >= nSectorSize && nOffset == 0 )
{ // 该扇区整个为需要的有效数据
if( ERROR_SUCCESS != FSDMGR_ReadDisk( lpVol->hDsk, dwStartSector, 1, lpBuf, nSectorSize ) )
goto _error_ret;
dwSize -= nSectorSize;
lpBuf += nSectorSize;
}
else
{ // 该扇区局部为需要的有效数据
if( ERROR_SUCCESS != FSDMGR_ReadDisk( lpVol->hDsk, dwStartSector, 1, pSector, nSectorSize ) )
goto _error_ret;
if( nOffset + dwSize >= nSectorSize )
{ // 数据跨扇区,拷贝从nOffset开始的余下扇区数据
memcpy( lpBuf, pSector + nOffset, nSectorSize - nOffset );
dwSize -= nSectorSize - nOffset;
lpBuf += nSectorSize - nOffset;
}
else
{ // 数据在扇区中间,拷贝需要部分
memcpy( lpBuf, pSector + nOffset, dwSize );
dwSize = 0;
}
bCache = TRUE; // CACHE 有效
}
// 如果还有,读取余下的数据.
while( dwSize )
{
dwStartSector = NEXT_SECTOR( lpVol->lpdwFat, dwStartSector );
if( dwStartSector != NULL_SECTOR )
{
if( dwSize >= nSectorSize )
{ // 余下的数据不小于一个扇区大小读取整个扇区
if( ERROR_SUCCESS != FSDMGR_ReadDisk( lpVol->hDsk, dwStartSector, 1, lpBuf, nSectorSize ) )
goto _error_ret;
dwSize -= nSectorSize;
lpBuf += nSectorSize;
bCache = FALSE;
}
else
{ // 余下的数据小于一个扇区大小读取扇区局部
if( ERROR_SUCCESS != FSDMGR_ReadDisk( lpVol->hDsk, dwStartSector, 1, pSector, nSectorSize ) )
goto _error_ret;
memcpy( lpBuf, pSector, dwSize );
dwSize = 0;
bCache = TRUE;
}
}
else
break;
}
}
if( lpCacheValid )
*lpCacheValid = bCache;
return s - dwSize;// 实际读的数据
_error_ret:
return 0;
}
// **************************************************
// 声明:static DWORD WriteSectors(
// LPKFSDVOL lpVol,
// DWORD dwStartSector,
// DWORD nOffset,
// const unsigned char * lpBuf,
// DWORD dwSize,
// LPBYTE pSector
// )
// 参数:
// IN lpVol - 卷对象结构指针
// IN dwStartSector - 开始扇区
// IN nOffset - 在扇区内偏移字节
// IN lpBuf - 用于写入数据的缓存
// IN dwSize - 需要写入的数据
// IN pSector - 用于读取扇区数据的临时缓存
// 返回值:
// 写入的数据大小
// 功能描述:
// 写入扇区数据,并返回实际写入的数据大小
// 引用:
// **************************************************
static DWORD WriteSectors( LPKFSDVOL lpVol,
DWORD dwStartSector,
DWORD nOffset,
const unsigned char * lpBuf,
DWORD dwSize,
LPBYTE pSector // temp buf
)
{
DWORD nSectorSize = lpVol->fdd.nBytesPerSector;
DWORD s = dwSize;
DEBUGMSG(FILE_ZONE, (TEXT("KFSD: WriteSector, Sector=%d, nOffset=%d, Size=%d.\r\n"), dwStartSector, nOffset, dwSize));
if( dwStartSector != NULL_SECTOR )
{
if( dwSize >= nSectorSize && nOffset == 0 )
{ // 首扇区整个为需要更新的有效数据
if( ERROR_SUCCESS != FSDMGR_WriteDisk( lpVol->hDsk, dwStartSector, 1, (LPBYTE)lpBuf, nSectorSize ) )
goto _error_ret; // 失败
dwSize -= nSectorSize;
lpBuf += nSectorSize;
}
else
{ // 首扇扇区局部为需要更新的有效数据,执行读取-更新-写入
if( ERROR_SUCCESS != FSDMGR_ReadDisk( lpVol->hDsk, dwStartSector, 1, (LPBYTE)pSector, nSectorSize ) )
goto _error_ret;
if( nOffset + dwSize >= nSectorSize )
{// 数据跨扇区,拷贝从nOffset开始的余下需要的扇区数据
memcpy( pSector + nOffset, lpBuf, nSectorSize - nOffset );
dwSize -= nSectorSize - nOffset;
lpBuf += nSectorSize - nOffset;
}
else
{// 数据在扇区中间,拷贝需要部分
memcpy( pSector + nOffset, lpBuf, dwSize );
dwSize = 0;
}
if( ERROR_SUCCESS != FSDMGR_WriteDisk( lpVol->hDsk, dwStartSector, 1, pSector, nSectorSize ) )
goto _error_ret; //写入磁盘失败
}
// 写入余下的部分
while( dwSize )
{
dwStartSector = NEXT_SECTOR( lpVol->lpdwFat, dwStartSector );
if( dwStartSector != NULL_SECTOR )
{
if( dwSize >= nSectorSize )
{// 整个扇区数据需要更新
if( ERROR_SUCCESS != FSDMGR_WriteDisk( lpVol->hDsk, dwStartSector, 1, (LPBYTE)lpBuf, nSectorSize ) )
goto _error_ret;
dwSize -= nSectorSize;
lpBuf += nSectorSize;
}
else
{// 局部扇区数据需要更新,执行读取-更新-写入
if( ERROR_SUCCESS != FSDMGR_ReadDisk( lpVol->hDsk, dwStartSector, 1, (LPBYTE)pSector, nSectorSize ) )
goto _error_ret;// 读错误
memcpy( pSector, lpBuf, dwSize );
dwSize = 0;
if( ERROR_SUCCESS != FSDMGR_WriteDisk( lpVol->hDsk, dwStartSector, 1, pSector, nSectorSize ) )
goto _error_ret;// 写错误
}
}
else
break;
}
}
return s - dwSize; // 实际写入的数据
_error_ret:
return 0;
}
// **************************************************
// 声明:static DWORD GetSerialNum(void)
// 参数:
// 无
// 返回值:
// 返回卷序列号
// 功能描述:
// 产生卷序列号
// 引用:
// **************************************************
static DWORD GetSerialNum(void)
{
return random();
}
// **************************************************
// 声明:static BOOL DoVolumeFormat( LPKFSDVOL lpVol )
// 参数:
// IN lpVol - 卷对象
// 返回值:
// 假如成功,返回TRUE; 否则,返回FALSE
// 功能描述:
// 格式化磁盘
// 引用:
// **************************************************
static BOOL DoVolumeFormat( LPKFSDVOL lpVol )
{
DWORD i, n;
DWORD dwfat;
void * pSector;
PRFH prfh;
DWORD hDsk;
BOOL bRetv = FALSE;
DEBUGMSG(FILE_ZONE, (TEXT("KFSD: Do Format Start\r\n")));
EnterCriticalSection( &lpVol->csFat ); // 进入冲突段
pSector = lpVol->lpSectorBuf;
if( pSector )
{
memset( pSector, 0, lpVol->fdd.nBytesPerSector );
hDsk = lpVol->hDsk;
// 初始化 prfh 结构
prfh = (PRFH)pSector;
memcpy( prfh->idName, idRam, strlen( idRam ) );
// now setup a ram alloc table
dwfat = ( ( (lpVol->fdd.nSectors * sizeof( DWORD ) + lpVol->fdd.nBytesPerSector - 1) / lpVol->fdd.nBytesPerSector ) * lpVol->fdd.nBytesPerSector );
i = dwfat / lpVol->fdd.nBytesPerSect
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -