📄 kmfs.c
字号:
/******************************************************
Copyright(c) 版权所有,1998-2003微逻辑。保留所有权利。
******************************************************/
/*****************************************************
文件说明:巨果.Kingmos file sys
版本号:2.0.0
开发时期:2000
作者:李林
修改记录:
问题:是否需要这么多CS ?
问题:对lpVol->csNode的锁范围有问题?!当对节点进行操作时,应该有更大的锁范围
example KFSD_MoveFile的锁范围
KFSD_DeleteFile 没有锁!!!
问题:我应该将file sector cache ptr放到file node struct文件节点,而不是
open file struct ?!
******************************************************/
#ifdef WINCE_EML
#include <windows.h>
#include <winioctl.h>
#include <diskio.h>
#include <string.h>
#include <fat.h>
#else
#include <eframe.h>
#include <efile.h>
#include <edevice.h>
#include <eassert.h>
#include <eobjlist.h>
#include <efsdmgr.h>
#include <epdev.h>
#include <epfs.h>
#include <estring.h>
#include <estdlib.h>
#include <eshell.h>
#include <diskio.h>
#endif
#define EFILE_VERSION MAKE_VERSION( 2, 0, 0 )
#define NULL_SECTOR 0xffffffff
#define USER_NODES 2
#define ALL_NODES 0
const TCHAR idRam[] = TEXT("KMFS");
const TCHAR szVolMark[] = TEXT( "\\Vol:" );
// size of RAM_FILE_HEAD = Sector size, Sector Size must >= 32 bytes
// 定义文件系统头结构
typedef struct _RAM_FILE_HEAD
{
BYTE idName[4]; // 标识 = KMFS
DWORD ver; // 版本号
DWORD dwSerialNum; // 序列号
DWORD dwTotalSectors; // 该磁盘总的扇区数
DWORD dwFatStartSector; // 该磁盘FAT开始扇区 file alloc table start sector
DWORD dwFatSectorNum; // 该磁盘FAT扇区数 file alloc sector number
DWORD dwFreeSector; // 该磁盘空闲扇区开始位置
DWORD nFreeCount; // 该磁盘空闲扇区数
DWORD dwDataStartSector; // 该磁盘数据扇区开始位置 data start sector
}RAM_FILE_HEAD, * PRFH;
//#define FILE_NAME_LEN (28+1+3)
// align 32 byte
// 文件节点为可以用标志
#define NODE_EMPTY 0
// 文件节点为删除标志
#define NODE_DELETED 0xfe
// 文件节点为占用标志
#define NODE_MARK 0xef
#define IS_NAME_BREAK( b ) ( (b) == '\\' || (b) == '/' )
#define GET_NODE_TYPE( lpNode ) ( (lpNode)->bFlag )
#define NODE_ALIGN_SIZE 32
#define MAX_FILE_NAME_LEN 256
#define NODE_RESERVE_NAME_LEN 12
// 定义文件磁盘节点数据结构,注意:该数据结构大小等于 NODE_ALIGN_SIZE
// the node struct must == NODE_ALIGN_SIZE and the strName must >= 2, because the name :'..'3
typedef struct _NODE
{
BYTE bFlag; // = NODE_EMPTY; NODE_DELETED; NODE_MARK
BYTE bNameLen; // 文件名长度, file name length
WORD wAttrib; // 文件属性 file attrib
DWORD dwStartSector; // 文件数据开始扇区
FILETIME ft; // 文件创建时间 create time 8 byte
DWORD nFileLength; // 文件长度 4 byte
char strName[NODE_RESERVE_NAME_LEN];// file name 11 byte
}NODE, * PNODE;
#define MAX_NODE_BYTES ( ( MAX_FILE_NAME_LEN + sizeof( NODE ) - NODE_RESERVE_NAME_LEN + NODE_ALIGN_SIZE - 1 ) / NODE_ALIGN_SIZE * NODE_ALIGN_SIZE )
#define GET_NODE_SIZE( pNode ) ( (pNode)->bNameLen + sizeof( NODE ) - NODE_RESERVE_NAME_LEN )
#define GET_NODE_ATTRIB_SIZE( pNode ) ( sizeof( NODE ) - NODE_RESERVE_NAME_LEN )
#define GET_NODE_NUM( pNode ) ( ( (pNode)->bNameLen + sizeof( NODE ) - NODE_RESERVE_NAME_LEN + NODE_ALIGN_SIZE - 1 ) / NODE_ALIGN_SIZE )
//定义打开文件节点结构
typedef struct _FILENODE
{
struct _FILENODE *lpNext; // 指向下一个已打开文件结构
LPTSTR lpszFileName; // 当前打开文件路径名 full path name
PNODE pNode; // 文件节点数据指针
DWORD dwRefCount; // 对该文件的引用数
DWORD dwFolderSector;// 该文件所在的文件夹数据的开始扇区 folder's first sector of file node's
DWORD dwNodeSector;// 文件节点所在的扇区 file node at the which sector
DWORD index;// 文件节点在扇区的索引号。file node index at the sector
CRITICAL_SECTION csFileNode; // 冲突段
BYTE bNodeBuf[MAX_NODE_BYTES]; // 为节点准备的缓存。a buf for pNode, the pNode pointer the buffer
}FILENODE, * LPFILENODE;
//
struct _KFSDVOL;
// 定义查找文件结构
typedef struct SF{
struct SF * lpNext; // 指向下一个当前系统已打开查找文件对象
// in
struct _KFSDVOL FAR * lpVol; // 卷对象
HANDLE hProc; // 该查找结构的拥有者
LPTSTR lpszName; // 需要查找的文件路径 path file name
void * pSector; //一个扇区大小的指针,用于读取数据
PNODE pCurNode; // 当前文件节点
//
DWORD dwFolderStartSector; // 当前文件节点所在的文件夹数据的开始扇区 start sector of the folder
DWORD dwCurNodeSector; // 当前文件节点所在扇区 current sector with pSector
WORD nCurNodeIndex; // 当前文件节点在扇区的索引 current index with pSector
WORD nCurNodeNum; // 当前文件节点所占的节点数(每节点32bytes)
DWORD dwCurNameLen; // 当前文件名长度 current file name len
LPTSTR lpszCurName; // 当前文件名指针 current file name
DWORD dwAddNodeSector; // 在搜索过程中发现的空闲节点 sector of has empty node in current sector
UINT nEmptyNodeIndex; // 在搜索过程中发现的空闲节点索引号 index of has empty node in current sector
UINT nDelNodeIndex; // 在搜索过程中发现的已删除节点
UINT nFreeNodeNum; // 在搜索过程中发现的已删除节点索引号
}SF, * PSF;
#define NORMAL_FILE 0
#define VOL_FILE 1
// 定义打开文件结构
typedef struct _KFSDFILE
{
struct _KFSDFILE * lpNext; // 指向下一个当前系统已打开文件对象
struct _KFSDVOL FAR * lpVol; // 当前文件所在的卷对象
HANDLE hProc; // 当前打开文件对象的拥有者
DWORD dwAccess; // 当前打开文件的存取模式
DWORD dwShareMode; // 当前打开文件的共享模式
DWORD dwCreate; // 当前打开文件的创建模式
DWORD dwFlagsAndAttributes; // 调用CreateFile时的 文件标志和属性
//
DWORD flag; // 文件标志:1 normal file, 0, vol file
DWORD dwFilePointer; // 当前打开文件存取位置
LPBYTE lpbCacheBuf; // 缓冲,用于加速
UINT uiCacheValid; // 缓冲数据有效标志
DWORD dwCachePosStart; //缓冲数据在文件的开始位置
LPFILENODE lpfn; // 文件在磁盘中的节点数据
}KFSDFILE, FAR * LPKFSDFILE;
#define GET_NODE_PTR( lpFile ) ( (lpFile)->lpfn->pNode )
#define GET_NODE_OFFSET( index, lpVol ) ( (index) % (lpVol)->nNodesPerSector * NODE_ALIGN_SIZE )
typedef SF KFSDFIND;
typedef SF FAR * LPKFSDFIND;
// 定义打开卷结构
typedef struct _KFSDVOL
{
struct _KFSDVOL * lpNext;// 指向下一个当前系统已打开卷对象
HVOL hVol; // 卷句柄
HDSK hDsk; // 卷所连接的磁盘
TCHAR szVolName[32]; // 卷名
FSD_DISK_DATA fdd; //磁盘信息
RAM_FILE_HEAD rfh; // KFSD文件系统头
WORD fUpdate; // 是否以刷新
WORD nNodesPerSector; // 每个扇区的节点数
#define FATBYTES ( sizeof( DWORD ) )
DWORD * lpdwFat; // 该卷的文件分配表 file alloc table
DWORD dwMinNeedUpdate; // 该卷的文件分配表需要更新的开始位置
DWORD dwMaxNeedUpdate; // 该卷的文件分配表需要更新的结束位置
CRITICAL_SECTION csNode; // 存取节点用的冲突段
CRITICAL_SECTION csFat; // 存取FAT表用的冲突段
CRITICAL_SECTION csFileList; // 存取打开文件用的冲突段
CRITICAL_SECTION csFindList;// 存取查找文件用的冲突段
LPKFSDFILE lpOpenFile; // 已打开文件对象链表
LPKFSDFIND lpFindFile; // 已打开查找对象链表
SHELLFILECHANGEFUNC pscf; // 向系统通知改变的回调函数
TCHAR szNotifyPath0[MAX_PATH];// 向系统通知需要的缓存1
TCHAR szNotifyPath1[MAX_PATH];// 向系统通知需要的缓存2
LPVOID lpSectorBuf; // 为卷读写扇区的临时缓存
}KFSDVOL, FAR * LPKFSDVOL;
#define FILE_ZONE 0
#define FILE_ERROR 1
static LPKFSDVOL lpListVol = NULL; // 已打开卷链表
static CRITICAL_SECTION csVolumeList; // 存取卷链表的冲突段
static LPKFSDVOL CreateVolume( void );
static BOOL RemoveVolume( LPKFSDVOL );
static LPKFSDVOL FindVolume( HDSK hDsk );
static BOOL AddToVolumeList( LPKFSDVOL );
static DWORD ReadSectors( LPKFSDVOL lpVol, DWORD dwStartSector,
DWORD nOffset, LPBYTE lpBuf, DWORD dwSize,
LPBYTE pSector, UINT * lpCacheValid );
static DWORD WriteSectors( LPKFSDVOL lpVol,
DWORD dwStartSector,
DWORD nOffset,
const unsigned char * lpBuf,
DWORD dwSize,
LPBYTE pSector // temp buf
);
static BOOL BeginSearch( SF * lpsf, LPKFSDVOL lpVol, HANDLE hProc, LPTSTR lpszName );
static BOOL SearchNode(
SF * lpsf );
static void EndSearch( SF * lpsf );
static BOOL AddFileHandleToVolume( LPKFSDFILE lpFile );
static BOOL AddFindHandleToVolume( LPKFSDFIND lpFind );
static LPCTSTR IgnoreSpace( LPCTSTR lpcszFileName );
#ifdef WINCE_EML
#define STATIC
#endif
#ifdef KINGMOS
#define STATIC static
#endif
STATIC BOOL KFSD_CloseFile( PFILE pf );
STATIC BOOL KFSD_CloseVolume( PVOL pVol );
STATIC BOOL KFSD_CopyFile( PVOL pVol, LPCTSTR lpExistingFileName, LPCTSTR lpNewFileName, BOOL bFailIfExists );
STATIC BOOL KFSD_CreateDirectory( PVOL pVol, LPCTSTR lpszPathName, PSECURITY_ATTRIBUTES pSecurityAttributes );
STATIC HANDLE KFSD_CreateFile( PVOL pVol, HANDLE hProc, LPCTSTR lpszFileName, DWORD dwAccess, DWORD dwShareMode,PSECURITY_ATTRIBUTES pSecurityAttributes, DWORD dwCreate,DWORD dwFlagsAndAttributes, HANDLE hTemplateFile );
STATIC BOOL KFSD_DeleteAndRenameFile( PVOL pVol, LPCTSTR lpszOldFileName, LPCTSTR lpszNewFileName );
STATIC BOOL KFSD_DeleteFile( PVOL pVol, LPCTSTR lpszFileName );
STATIC BOOL KFSD_DeviceIoControl( DWORD pf, DWORD dwIoControlCode, LPVOID pInBuf, DWORD nInBufSize, LPVOID pOutBuf, DWORD nOutBufSize, LPDWORD pBytesReturned );
STATIC BOOL KFSD_FindClose( PFIND pfd );
STATIC HANDLE KFSD_FindFirstFile( PVOL pVol, HANDLE hProc, LPCTSTR lpszFileSpec, FILE_FIND_DATA * pfd );
STATIC BOOL KFSD_FindNextFile( PFIND pfd, FILE_FIND_DATA * pffd );
STATIC BOOL KFSD_FlushFileBuffers( PFILE pf );
STATIC BOOL KFSD_GetDiskFreeSpace( PVOL pVol, LPCTSTR lpszPathName, LPDWORD pSectorsPerCluster, LPDWORD pBytesPerSector, LPDWORD pFreeClusters, LPDWORD pClusters );
STATIC DWORD KFSD_GetFileAttributes( PVOL pVol, LPCTSTR lpszFileName );
STATIC BOOL KFSD_GetFileInformationByHandle( PFILE pf, FILE_INFORMATION * phfi );
STATIC DWORD KFSD_GetFileSize( PFILE pf, LPDWORD pFileSizeHigh );
STATIC BOOL KFSD_GetFileTime( PFILE pf, FILETIME * pft, FILETIME *, FILETIME * );
STATIC BOOL KFSD_MountDisk( HDSK hdsk );
STATIC BOOL KFSD_MoveFile( PVOL pVol, LPCTSTR lpszOldFileName, LPCTSTR lpszNewFileName );
STATIC void KFSD_Notify( PVOL pVol, DWORD dwFlags );
STATIC BOOL KFSD_ReadFile( PFILE pf, LPVOID lpBuffer, DWORD dwNumToRead, LPDWORD lpdwNumRead, LPOVERLAPPED pOverlapped );
STATIC BOOL KFSD_ReadFileWithSeek( PFILE pf, LPVOID pBuffer, DWORD cbRead, LPDWORD pcbRead, LPOVERLAPPED pOverlapped, DWORD dwLowOffset, DWORD dwHighOffset);
STATIC BOOL KFSD_RegisterFileSystemFunction( PVOL pVol, SHELLFILECHANGEFUNC pft );
STATIC BOOL KFSD_RemoveDirectory( PVOL pVol,LPCTSTR lpszPathName );
STATIC BOOL KFSD_SetEndOfFile( PFILE pf );
STATIC BOOL KFSD_SetFileAttributes( PVOL pVol, LPCTSTR lpszFileName, DWORD dwFileAttributes );
STATIC DWORD KFSD_SetFilePointer( PFILE pf, LONG lDistanceToMove, LPLONG pDistanceToMoveHigh, DWORD dwMothod );
STATIC BOOL KFSD_SetFileTime( PFILE pf, const FILETIME *pft, const FILETIME *, const FILETIME * );
STATIC BOOL KFSD_UnmountDisk( HDSK hdsk );
STATIC BOOL KFSD_WriteFile( PFILE pf, LPCVOID lpBuffer, DWORD dwNumToWrite, LPDWORD lpdwNumWrite, LPOVERLAPPED pOverlapped );
STATIC BOOL KFSD_WriteFileWithSeek( PFILE pFile, LPCVOID pBuffer, DWORD cbWrite, LPDWORD pcbWritten, DWORD dwLowOffset, DWORD dwHighOffset );
#define NEXT_SECTOR( pfat, dwSector ) (*((pfat)+(dwSector)))
#ifdef KINGMOS
// 文件系统驱动程序接口
static const FSDDRV drvFSD = {
KFSD_CloseFile,
KFSD_CloseVolume,
KFSD_CreateDirectory,
KFSD_CreateFile,
KFSD_DeleteAndRenameFile,
KFSD_DeleteFile,
KFSD_DeviceIoControl,
KFSD_FindClose,
KFSD_FindFirstFile,
KFSD_FindNextFile,
KFSD_FlushFileBuffers,
KFSD_GetDiskFreeSpace,
KFSD_GetFileAttributes,
KFSD_GetFileInformationByHandle,
KFSD_GetFileSize,
KFSD_GetFileTime,
KFSD_MountDisk,
KFSD_MoveFile,
KFSD_Notify,
KFSD_ReadFile,
KFSD_ReadFileWithSeek,
KFSD_RegisterFileSystemFunction,
KFSD_RemoveDirectory,
KFSD_SetEndOfFile,
KFSD_SetFileAttributes,
KFSD_SetFilePointer,
KFSD_SetFileTime,
KFSD_UnmountDisk,
KFSD_WriteFile,
KFSD_WriteFileWithSeek,
KFSD_CopyFile
};
// **************************************************
// 声明:BOOL _InstallKMFS( void )
// 参数:
// 无
// 返回值:
// 假如成功,返回TRUE; 否则,返回FALSE
// 功能描述:
// 初始化系统默认文件系统
// 引用:
// filesrv.c
// **************************************************
BOOL _InstallKMFS( void )
{
InitializeCriticalSection( &csVolumeList );
#ifdef __DEBUG
csVolumeList.lpcsName = "CS-VOL";
#endif
return FSDMGR_RegisterFSD ( "KFSD", &drvFSD );
}
// **************************************************
// 声明:void _UnInstallKMFS( void )
// 参数:
// 无
// 返回值:
// 无
// 功能描述:
// 与 _InstallKMFS 相反,注销Kimgos file system
// 引用:
// **************************************************
void _UnInstallKMFS( void )
{
FSDMGR_UnregisterFSD( "KMFS" );
DeleteCriticalSection( &csVolumeList );
}
#endif
static BOOL AccessTest( LPKFSDVOL pVolume )
{
// 卷是否可写。check volume is write enable ?
if( (pVolume->fdd.dwFlags & DISK_INFO_FLAG_READONLY) )
{ // 不可写。error
WARNMSG( FILE_ZONE, ( "error in AccessTest ACCESS_DENIED.\r\n" ) );
SetLastError(ERROR_ACCESS_DENIED);
return FALSE;
}
//
return TRUE;
}
// **************************************************
// 声明:static LPFILENODE CreateFileNode( LPCTSTR lpcszFileName )
// 参数:
// IN lpcszFileName - 文件名
// 返回值:
// 假如成功,返回新分配的文件节点指针;否则,返回NULL
// 功能描述:
// 创建文件节点指针
// 引用:
// **************************************************
static LPFILENODE CreateFileNode( LPCTSTR lpcszFileName )
{
LPFILENODE lpfn = ( LPFILENODE)malloc( sizeof( FILENODE ) + (strlen( lpcszFileName ) + 1) * sizeof( TCHAR ) );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -