📄 fsmain.c
字号:
/******************************************************
Copyright(c) 版权所有,1998-2003微逻辑。保留所有权利。
******************************************************/
/*****************************************************
文件说明:文件系统主调用界面
版本号:1.0.0
开发时期:2000
作者:李林
修改记录:
******************************************************/
#include <eframe.h>
#include <efile.h>
#include <edevice.h>
#include <eapisrv.h>
#include <eobjlist.h>
#include <efsdmgr.h>
#include <epdev.h>
#include <epfs.h>
#include <filesrv.h>
static const TCHAR sysVolume[] = "\\disk0";
#define SPECIAL_ATTRIB (FILE_ATTRIBUTE_DEVICE|FILE_ATTRIBUTE_SPARSE_FILE|FILE_ATTRIBUTE_REPARSE_POINT|FILE_ATTRIBUTE_COMPRESSED|FILE_ATTRIBUTE_ENCRYPTED|FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_ROM)
#define FSMAIN_ZONE 0
// **************************************************
// 声明:_LPFILEDATA _GetHFILEPtr( HANDLE hFile )
// 参数:
// IN hFile - 文件对象
// 返回值:
// 假如有效,返回非NULL文件对象指针;否则,返回NULL
// 功能描述:
// 验证文件对象的有效性并返回有效的指针
// 引用:
//
// **************************************************
static _LPFILEDATA _GetHFILEPtr( HANDLE hFile )
{
if( hFile == 0 || hFile == INVALID_HANDLE_VALUE )
return NULL;
return (_LPFILEDATA)hFile;
}
// **************************************************
// 声明:_LPFINDDATA _GetHFINDPtr( HANDLE hfd )
// 参数:
// IN hfd - 文件查找对象
// 返回值:
// 假如有效,返回非NULL文件查找对象指针;否则,返回NULL
// 功能描述:
// 验证文件对象的有效性并返回有效的指针
// 引用:
//
// **************************************************
_LPFINDDATA _GetHFINDPtr( HANDLE hfd )
{
if( hfd && hfd != INVALID_HANDLE_VALUE )
{
_LPFINDDATA lpfd = (_LPFINDDATA)hfd;
if( lpfd->obj.objType == OBJ_FINDFILE )
return lpfd; // 有效
}
return NULL;
}
// **************************************************
// 声明:static int CheckFilePathName( LPCTSTR lpfpn )
// 参数:
// IN lpfpn - 文件名
// 返回值:
// 假如成功,返回文件名的长度;否则,返回0
// 功能描述:
// 验证文件名的有效性
// 引用:
//
// **************************************************
static int CheckFilePathName( LPCTSTR lpfpn )
{
if( lpfpn )
{
int iMaxLen;
iMaxLen = strlen( lpfpn );
if( iMaxLen < MAX_PATH )
return iMaxLen;
}
SetLastError( ERROR_INVALID_PARAMETER );
return 0;
}
// **************************************************
// 声明:static int _GetObjName( LPCTSTR lpfn, UINT * lpNameLen )
// 参数:
// IN lpfn - 完整的路径名
// OUT lpNameLen - 用于接受存储对象名的长度
// 返回值:
// 返回存储对象的类型,可以为以下值:
// 0 - 不知道
// 1 - 设备类型,例如:"COM2:"
// 2 - 文件类型,例如:"\\folder\\test.txt"
//
// 功能描述:
// 得到对象名类型
// 引用:
//
// **************************************************
static int _GetObjName( LPCTSTR lpfn, UINT * lpNameLen )
{
int type = 0;
int i;
*lpNameLen = 0;
for( i = 0; i < 5 && *lpfn && *lpfn != '\\'; i++ )
lpfn++;
if( i == 5 && *(lpfn-1) == ':' )
{
type = 1; // 设备类型,device type
*lpNameLen = 4;
}
else
{
if( *lpfn != '\\' )
return 0; // 错误
lpfn++;
i++;
while( *lpfn && *lpfn != '\\' )
{
i++;
lpfn++;
}
type = 2; // 文件类型 file type
*lpNameLen = i;
}
return type;
}
// **************************************************
// 声明:static _LPVOLUME _GetVolumePtr( LPCTSTR lpcszFileName, UINT * pLen )
// 参数:
// IN lpcszFileName - 包含卷名的文件指针(可以为NULL,这时代表用系统默认卷),例如:"\\storage disk\\filename.ext"
// IN/OUT pLen - 卷名长度,当lpcszFileName为NULL时,输出默认卷名的长度
// 返回值:
// 无
// 功能描述:
// 根据卷名得到地区当前系统存在的卷对象指针,如果卷名为NULL,则得到系统默认卷;
// 系统默认卷是一个“根卷”
// 引用:
//
// **************************************************
static _LPVOLUME _GetVolumePtr( LPCTSTR lpcszFileName, UINT * pLen )
{
_LPVOLUME lpVol = NULL;
if( lpcszFileName[*pLen] == '\\' ) // 检查是否合法
lpVol= (_LPVOLUME)_FileMgr_FindVolume( lpcszFileName, *pLen );
if( lpVol == NULL )
{ // 用系统默认卷use sysVolume
lpVol= (_LPVOLUME)_FileMgr_FindVolume( sysVolume, 6 );
*pLen = 0;
}
return lpVol;
}
// **************************************************
// 声明:static BOOL _CopyFile( HANDLE hFileDest, HANDLE hFileSrc )
// 参数:
// IN hFileDest - 目标文件
// IN hFileSrc - 源文件
// 返回值:
// 假如成功,返回TRUE; 否则,返回FALSE
// 功能描述:
// 将源文件内容拷贝到目标文件
// 引用:
//
// **************************************************
#define MAX_COPY_CACHE_SIZE (32 * 1024)
#define COPY_FILE_ZONE 1
static BOOL _CopyFile( HANDLE hFileDest, HANDLE hFileSrc )
{
int unit = MAX_COPY_CACHE_SIZE;
DWORD dwSize;
void *p, * lpBuf = NULL;
BOOL bRetv = FALSE;
ASSERT( hFileDest && hFileSrc );
while( lpBuf == NULL && unit >= 128 )
{
DWORD dwRealAllocSize;
lpBuf = Page_AllocMem( unit, &dwRealAllocSize, 0 ); // 分配以页为单位的
if( lpBuf )
{ // 分配成功
unit = dwRealAllocSize;
break;
}
unit >>= 1; //分配不成功,用较小的大小来试
}
if( lpBuf )
{
dwSize = FileSys_GetSize( hFileSrc, NULL );
if( FileSys_SetPointer( hFileDest, dwSize, NULL, FILE_BEGIN ) == INVALID_SET_FILE_POINTER )
goto _error;
// 将目标文件的大小设为与源文件大小相同
if( FileSys_SetEnd( hFileDest ) == FALSE )
goto _error;
FileSys_SetPointer( hFileDest, 0, NULL, FILE_BEGIN );
p = lpBuf;
// 逐段拷贝文件内容
while( 1 )
{
if( (bRetv = FileSys_Read( hFileSrc, p, unit, &dwSize, NULL )) == TRUE )
{
if( dwSize == 0 )
break; // end of file
else
FileSys_Write( hFileDest, p, dwSize, &dwSize, NULL );
}
else
break;
}
_error:
Page_FreeMem( lpBuf, unit ); // 释放之前分配的缓存
}
else
{
DEBUGMSG( FSMAIN_ZONE, ( "no enough memory when CopyFile.\r\n" ) );
}
return bRetv;
}
// **************************************************
// 声明:static BOOL IsSystemProtected( LPCTSTR lpcszPathName )
// 参数:
// IN lpcszPathName - 文件路径名
// 返回值:
// 假如成功,返回TRUE; 否则,返回FALSE
// 功能描述:
// 检查文件是否是系统预留名字
// 引用:
//
// **************************************************
static BOOL IsSystemProtected( LPCTSTR lpcszPathName )
{ // disk0~disk9 if protected by system
int uiLen = strlen( lpcszPathName );
if( *lpcszPathName == '\\' )
{
lpcszPathName++;
uiLen--;
}
if( uiLen == 5 )
{
if( lpcszPathName[4] >= '0' && lpcszPathName[4] <= '9' &&
strnicmp( "disk", lpcszPathName, 4 ) == 0 )
{
SetLastError( ERROR_ACCESS_DENIED );
return TRUE;
}
}
return FALSE;
}
// **************************************************
// 声明:BOOL WINAPI KL_CreateDirectory(
// LPCTSTR lpcszPathName,
// PSECURITY_ATTRIBUTES pSecurityAttributes )
// 参数:
// IN lpcszPathName - 路径名
// IN pSecurityAttributes - 安全属性(不支持,为NULL)
// 返回值:
// 假如成功,返回TRUE; 否则,返回FALSE
// 功能描述:
// 创建文件夹
// 引用:
// 内部使用
// **************************************************
BOOL WINAPI KL_CreateDirectory( LPCTSTR lpcszPathName, PSECURITY_ATTRIBUTES pSecurityAttributes)
{
int type;
UINT uLen;
if( CheckFilePathName( lpcszPathName ) ) // 检查文件名是否合法
{
type = _GetObjName( lpcszPathName, &uLen ); // 得到对象类型
if( type == 2 )
{ // 文件类型 file
// 得到该文件对应的卷对象指针
_LPVOLUME lpVol = _GetVolumePtr( lpcszPathName, &uLen );
if( lpVol && lpVol->lpdsk->lpfsd->lpCreateDirectory )
{
if( Sys_CaptureException() == EXCEPTION_NO_ERROR )
{
BOOL bRetv;
bRetv = lpVol->lpdsk->lpfsd->lpCreateDirectory( lpVol->pVol, lpcszPathName + uLen, pSecurityAttributes );
Sys_ReleaseException();
return bRetv;
}
}
}
}
return FALSE;
}
// **************************************************
// 声明:BOOL WINAPI FileSys_CreateDirectory( LPCTSTR lpcszPathName, PSECURITY_ATTRIBUTES pSecurityAttributes)
// 参数:
// IN lpcszPathName - 路径名
// IN pSecurityAttributes - 安全属性(不支持,为NULL)
// 返回值:
// 假如成功,返回TRUE; 否则,返回FALSE
// 功能描述:
// 创建文件夹
// 引用:
// 系统API
// **************************************************
BOOL WINAPI FileSys_CreateDirectory( LPCTSTR lpcszPathName, PSECURITY_ATTRIBUTES pSecurityAttributes)
{
if( IsSystemProtected( lpcszPathName ) ) // 该文件名是否已经被保护 ?
return FALSE; // 是,被保护,返回错误
return KL_CreateDirectory( lpcszPathName, pSecurityAttributes ); //
}
// **************************************************
// 声明:static _LPFILEDATA _CreateFile(
// LPCTSTR lpcszFileName,
// DWORD dwAccess,
// DWORD dwShareMode,
// PSECURITY_ATTRIBUTES pSecurityAttributes,
// DWORD dwCreate,
// DWORD dwFlagsAndAttributes,
// HANDLE hTemplateFile )
// 参数:
// IN lpcszFileName-文件名
// IN fAccess-存取控制,由以下值的位组合:
// GENERIC_WRITE-读操作
// GENERIC_READ-写操作
// IN wShareMode-共享模式,由以下值的位组合:
// FILE_SHARE_READ-共享读
// FILE_SHARE_WRITE-共享写
// IN pSecurityAttributes-安全设置(不支持,为NULL)
// IN dwCreate-创建方式,包含:
// CREATE_NEW-创建新文件;假如文件存在,则失败
// CREATE_ALWAYS-创建文件;假如文件存在,则覆盖它
// OPEN_EXISTING-打开文件;假如文件不存在,则失败
// OPEN_ALWAYS-打开文件;假如文件不存在,则创建
// IN dwFlagsAndAttributes-文件属性
// IN hTemplateFile-临时文件句柄(不支持,为NULL)
// 返回值:
// 文件结构指针
// 功能描述:
// 创建文件
// 引用:
// 内部使用
// **************************************************
static _LPFILEDATA _CreateFile(
LPCTSTR lpcszFileName,
DWORD dwAccess,
DWORD dwShareMode,
PSECURITY_ATTRIBUTES pSecurityAttributes,
DWORD dwCreate,
DWORD dwFlagsAndAttributes,
HANDLE hTemplateFile )
{
int type;
UINT uLen;
_LPFILEDATA lpfd;
DEBUGMSG( FSMAIN_ZONE, ( "_CreateFile.\r\n" ) );
lpfd = (_LPFILEDATA)malloc( sizeof( _FILEDATA ) ); // 分配文件句柄结构
if( lpfd == NULL )
return INVALID_HANDLE_VALUE;
lpfd->pFile = (PFILE)INVALID_HANDLE_VALUE; // 先初始化为无效的值
type = _GetObjName( lpcszFileName, &uLen ); // 得到对象类型
if( type == 1 )
{ // 设备对象 device
lpfd->hVol = 0;
lpfd->pFile = (DWORD)Dev_CreateFile(
lpcszFileName,
dwAccess,
dwShareMode,
GetCallerProcess() );
}
else if( type == 2 )
{ // 文件对象 file
_LPVOLUME lpVol = _GetVolumePtr( lpcszFileName, &uLen ); // 得到卷对象
if( Sys_CaptureException() == EXCEPTION_NO_ERROR )
{
if( lpVol && lpVol->lpdsk->lpfsd->lpCreateFile )
{
lpfd->hVol = (HVOL)lpVol;
lpfd->pFile = (PFILE)lpVol->lpdsk->lpfsd->lpCreateFile(
lpVol->pVol,
GetCallerProcess(),
lpcszFileName + uLen,
dwAccess,
dwShareMode,
pSecurityAttributes,
dwCreate,
dwFlagsAndAttributes,
hTemplateFile );
}
Sys_ReleaseException();
}
}
if( lpfd->pFile != (DWORD)INVALID_HANDLE_VALUE )
{ // 创建文件成功
return lpfd;
}
else
{ // 不成功,释放之前分配的指针
free( lpfd );
return INVALID_HANDLE_VALUE;
}
}
// **************************************************
// 声明:HANDLE WINAPI FileSys_CreateFile(
// LPCTSTR lpcszFileName,
// DWORD dwAccess,
// DWORD dwShareMode,
// PSECURITY_ATTRIBUTES pSecurityAttributes,
// DWORD dwCreate,
// DWORD dwFlagsAndAttributes,
// HANDLE hTemplateFile )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -