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

📄 kmfs.c

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