bool CWpf::WpfOpen(const char * strPathName,__int64 iOffset,DWORD dwOpenType)
{
if(strPathName == NULL || dwOpenType == 0)
{
m_eWrLastError = EWR_PARA_ERROR;
return false;
}
if(m_bSaving)
{
m_eWrLastError = EWR_FILE_SAVING;
return false;
}
//先关闭当前打开的wpf文件
WpfClose();
m_strWpfDir = strPathName;
replace(m_strWpfDir.begin(),m_strWpfDir.end(),'/','\\');
size_t iPos = m_strWpfDir.find_last_of("\\");
if (iPos != string::npos)
{
m_strWpfFileName = m_strWpfDir.substr(iPos + 1,m_strWpfDir.length() - iPos - 1);
m_strWpfDir = m_strWpfDir.substr(0,iPos);
}
//打开或创建文件
errno_t err = 0;
if (dwOpenType & EWOT_RDWR)
{
err = _sopen_s(&(m_iFileHandle[EFT_MAIN]), strPathName, _O_BINARY | _O_RDWR , _SH_DENYWR, _S_IREAD | _S_IWRITE );
dwOpenType |= EWOT_LISTDIR;
}
else
{
err = _sopen_s(&(m_iFileHandle[EFT_MAIN]), strPathName, _O_BINARY | _O_RDONLY , /*_SH_DENYWR*/_SH_DENYNO, _S_IREAD);
if (dwOpenType & EWOT_READONLY)
{
dwOpenType |= EWOT_LISTHASH;
}
}
if(err != 0)
{
m_eWrLastError = EWR_FILE_OPEN_FAIL;
return false;
}
for (int i = EFT_THREAD ; i < EFT_NUM; i ++)
{
err = _sopen_s(&(m_iFileHandle[i]), strPathName, _O_BINARY | _O_RDONLY , _SH_DENYNO, _S_IREAD);
if(err != 0)
{
m_eWrLastError = EWR_FILE_OPEN_FAIL;
return false;
}
}
m_iWpfStartPos = iOffset;
m_WpfHeader.dwMagic = 0;//防止有些文件长度不够sizeof(S_WpfHeader),取到默认值
m_WpfHeader_Bak.dwMagic = 0;//防止有些文件长度不够sizeof(S_WpfHeader),取到默认值
m_WpfHeader.bySavingHeader = TRUE;//防止有些文件长度不够sizeof(S_WpfHeader),取到默认值
m_WpfHeader_Bak.bySavingHeader = TRUE;//防止有些文件长度不够sizeof(S_WpfHeader),取到默认值
//读入文件头
_lseeki64(m_iFileHandle[EFT_MAIN],m_iWpfStartPos,SEEK_SET);
_read(m_iFileHandle[EFT_MAIN],&m_WpfHeader,sizeof(S_WpfHeader));
//读入文件头备份
_lseeki64(m_iFileHandle[EFT_MAIN],m_iWpfStartPos + sizeof(S_WpfHeader),SEEK_SET);
_read(m_iFileHandle[EFT_MAIN],&m_WpfHeader_Bak,sizeof(S_WpfHeader));
if(m_WpfHeader.bySavingHeader && m_WpfHeader_Bak.bySavingHeader)//该文件在创建的时候出现异常,如断点,程序崩溃等情况,没有正常写入头
{
return false;
}
//如果上次文件头没有正确保存,读取必份的文件
if (m_WpfHeader.bySavingHeader)
{
m_WpfHeader = m_WpfHeader_Bak;
m_bModifyed = true;//原来没有保存好,用了备份的,那么这次即使没有修改也要重新保存
}
m_WpfHeader_Disk = m_WpfHeader;
if(m_WpfHeader.dwMagic != WPF_MAGIC)
{
m_eWrLastError = EWR_NOT_WPF_FILE;
WpfClose();
return false;
}
m_WpfHeader.bySavingHeader = FALSE;//理论上不可能出现文件头及备份文件头m_WpfHeader.bySavingHeader同时为TRUE,还是清一下标记
m_dwOpenType = dwOpenType;
//如果以写方式打开要求读入空闲块描述信息
if ((m_dwOpenType & EWOT_RDWR) && m_WpfHeader.dwBlankBlockSize > 0)
{
PBlankBlock pBlock = new BlankBlock[m_WpfHeader.dwBlankBlockSize];
_lseeki64(m_iFileHandle[EFT_MAIN],m_iWpfStartPos + m_WpfHeader.iBlankBlockPos,SEEK_SET);
_read(m_iFileHandle[EFT_MAIN],pBlock,m_WpfHeader.dwBlankBlockSize * sizeof(BlankBlock));
PBlankBlock p = pBlock;
PBlankBlockNode pList = NULL,pList2 = NULL;
pList = new BlankBlockNode();
pList->blankBlock.dwStart = p->dwStart;
pList->blankBlock.dwSize = p->dwSize;
pList->pParent = NULL;
pList->pNext = NULL;
m_pBlankBlockList = pList;
pList2 = pList;
p ++;
for (DWORD i = 1; i < m_WpfHeader.dwBlankBlockSize; i++,p++)
{
pList = new BlankBlockNode();
pList->blankBlock.dwStart = p->dwStart;
pList->blankBlock.dwSize = p->dwSize;
pList->pParent = pList2;
pList2->pNext = pList;
pList2 = pList;
}
pList2->pNext = NULL;
SAFE_DELETE_ARRAY(pBlock);
}
//载入文件分配表
return WpfLoadFat();
}
bool CWpf::WpfLoadFat()
{
if(!IsOpenWpfFile())
{
m_eWrLastError = EWR_FILE_NOT_OPEN;
return false;
}
if(m_WpfHeader.dwDirCount < 1)
{
m_eWrLastError = EWR_NOT_WPF_FILE;
return false;
}
_lseeki64(m_iFileHandle[EFT_MAIN],m_iWpfStartPos + m_WpfHeader.iFatPos,SEEK_SET);
DWORD dwCount = m_WpfHeader.dwDirCount + m_WpfHeader.dwFileCount;
if (m_bSpeedPrior)
{
m_pFcb1List = new FCB1[dwCount];
_read(m_iFileHandle[EFT_MAIN],m_pFcb1List,dwCount * FCB1_SIZE);
if (m_dwOpenType & EWOT_LISTHASH)
{
//hash map
PFCB1 pfcb1 = m_pFcb1List;
for (DWORD i = 0; i < dwCount; i++,pfcb1++)
{
#ifdef _DEBUG
if (pfcb1->iHashKey != 0 && m_MhashFcb1.find(pfcb1->iHashKey) != m_MhashFcb1.end())
{
int i = 3;
}
#endif
if (pfcb1->iHashKey != 0)
{
m_MhashFcb1[pfcb1->iHashKey] = pfcb1;
}
}
}
if (m_dwOpenType & EWOT_LISTDIR)//要求构造目录结构
{
m_pFcb2List = new FCB2[dwCount];
_read(m_iFileHandle[EFT_MAIN],m_pFcb2List,dwCount * FCB2_SIZE);
m_pFcbList = new FCB[dwCount];
memset(m_pFcbList,0,dwCount * sizeof(FCB));
m_pDirList = new WpfFileList[m_WpfHeader.dwDirCount];
//递归构造目录
vector<PWpfFileList> VDirs;
m_pWpfRoot = &(m_pDirList[0]);
m_pWpfRoot->pfcb = &(m_pFcbList[0]);
m_pWpfRoot->pfcb->pfcb1 = &(m_pFcb1List[0]);
m_pWpfRoot->pfcb->pfcb2 = &(m_pFcb2List[0]);
VDirs.push_back(m_pWpfRoot);
DWORD dwDirNo = 1,dwPos = 0;
PWpfFileList pFront = NULL;
while(!VDirs.empty())
{
pFront = VDirs.front();
dwPos = pFront->pfcb->pfcb1->dwStart;
for (DWORD i = 0; i < pFront->pfcb->pfcb1->dwSize; i++,dwPos++)
{
PFCB2 fcb2 = &(m_pFcb2List[dwPos]);
if(fcb2->dwAttribute & EFA_DIR)
{
PWpfFileList sublist = &(m_pDirList[dwDirNo]);
dwDirNo ++;
PFCB newfcb = &(m_pFcbList[dwPos]);
newfcb->pfcb1 = &(m_pFcb1List[dwPos]);
newfcb->pfcb2 = &(m_pFcb2List[dwPos]);
newfcb->pParent = pFront;
sublist->pfcb = newfcb;
VDirs.push_back(sublist);
pFront->MDirs[fcb2->strName] = sublist;
}
else if (fcb2->dwAttribute & EFA_FILE)
{
PFCB newfcb = &(m_pFcbList[dwPos]);
newfcb->pfcb1 = &(m_pFcb1List[dwPos]);
newfcb->pfcb2 = &(m_pFcb2List[dwPos]);
newfcb->pParent = pFront;
pFront->MFiles[fcb2->strName] = newfcb;
if (m_dwOpenType & EWOT_LISTFCBHASH)
{
m_MhashFcb[newfcb->pfcb1->iHashKey] = newfcb;
}
}
}
VDirs.erase(VDirs.begin());
}
}
}
else
{
m_pFcb1List = NULL;
m_pFcb2List = NULL;
m_pFcbList = NULL;
m_pDirList = NULL;
if (m_dwOpenType & EWOT_LISTHASH)
{
for (DWORD index = 0; index < dwCount; index ++)
{
PFCB1 pfcb1 = new FCB1();
_read(m_iFileHandle[EFT_MAIN],pfcb1,FCB1_SIZE);
//hash map
#ifdef _DEBUG
if (pfcb1->iHashKey != 0 && m_MhashFcb1.find(pfcb1->iHashKey) != m_MhashFcb1.end())
{
int i = 3;
}
#endif
if (pfcb1->iHashKey != 0)
{
m_MhashFcb1[pfcb1->iHashKey] = pfcb1;
}
}
}
if (m_dwOpenType & EWOT_LISTDIR)//要求构造目录结构
{
//递归构造目录
vector<PWpfFileList> VDirs;
m_pWpfRoot = new WpfFileList();
m_pWpfRoot->pfcb = new FCB();
m_pWpfRoot->pfcb->pfcb1 = new FCB1();
m_pWpfRoot->pfcb->pfcb2 = new FCB2();
VDirs.push_back(m_pWpfRoot);
//读取第一个根目录
_lseeki64(m_iFileHandle[EFT_MAIN],m_iWpfStartPos + m_WpfHeader.iFatPos,SEEK_SET);
_read(m_iFileHandle[EFT_MAIN],m_pWpfRoot->pfcb->pfcb1,FCB1_SIZE);
_lseeki64(m_iFileHandle[EFT_MAIN],m_iWpfStartPos + m_WpfHeader.iFatPos + dwCount * FCB1_SIZE,SEEK_SET);
_read(m_iFileHandle[EFT_MAIN],m_pWpfRoot->pfcb->pfcb2,FCB2_SIZE);
PWpfFileList pFront = NULL;
while(!VDirs.empty())
{
pFront = VDirs.front();
for (DWORD dwPos = pFront->pfcb->pfcb1->dwStart; dwPos < pFront->pfcb->pfcb1->dwStart + pFront->pfcb->pfcb1->dwSize; dwPos++)
{
PFCB2 fcb2 = new FCB2();
//读取这一条fcb2
_lseeki64(m_iFileHandle[EFT_MAIN],m_iWpfStartPos + m_WpfHeader.iFatPos + dwCount * FCB1_SIZE + dwPos * FCB2_SIZE,SEEK_SET);
_read(m_iFileHandle[EFT_MAIN],fcb2,FCB2_SIZE);
if(fcb2->dwAttribute & EFA_DIR)
{
PFCB newfcb = new FCB();
newfcb->pfcb1 = new FCB1();
//读取这一条fcb1
_lseeki64(m_iFileHandle[EFT_MAIN],m_iWpfStartPos + m_WpfHeader.iFatPos + dwPos * FCB1_SIZE,SEEK_SET);
_read(m_iFileHandle[EFT_MAIN],newfcb->pfcb1,FCB1_SIZE);
PWpfFileList sublist = new WpfFileList();
newfcb->pfcb2 = fcb2;
newfcb->pParent = pFront;
sublist->pfcb = newfcb;
VDirs.push_back(sublist);
pFront->MDirs[fcb2->strName] = sublist;
}
else if (fcb2->dwAttribute & EFA_FILE)
{
PFCB newfcb = new FCB();
newfcb->pfcb1 = new FCB1();
//读取这一条fcb1
_lseeki64(m_iFileHandle[EFT_MAIN],m_iWpfStartPos + m_WpfHeader.iFatPos + dwPos * FCB1_SIZE,SEEK_SET);
_read(m_iFileHandle[EFT_MAIN],newfcb->pfcb1,FCB1_SIZE);
newfcb->pfcb2 = fcb2;
newfcb->pParent = pFront;
pFront->MFiles[fcb2->strName] = newfcb;
if (m_dwOpenType & EWOT_LISTFCBHASH)
{
m_MhashFcb[newfcb->pfcb1->iHashKey] = newfcb;
}
}
}
VDirs.erase(VDirs.begin());
}
}
}
return true;
}