MakeMetaFile.cpp
资源名称:GGBT.rar [点击查看]
上传用户:lds876
上传日期:2013-05-25
资源大小:567k
文件大小:11k
源码类别:
P2P编程
开发平台:
Visual C++
- // MakeMetaFile.cpp: implementation of the CMakeMetaFile class.
- //
- //////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- #include "testbt.h"
- #include "MakeMetaFile.h"
- #include "filebase.h"
- #include "Val.h"
- #include "sha.h"
- #include "btformat.h"
- #include "Bdecode.h"
- #ifdef _DEBUG
- #undef THIS_FILE
- static char THIS_FILE[]=__FILE__;
- #define new DEBUG_NEW
- #endif
- //////////////////////////////////////////////////////////////////////
- // Construction/Destruction
- //////////////////////////////////////////////////////////////////////
- CMakeMetaFile::CMakeMetaFile()
- {
- m_hevDone = CreateEvent(0, true, false, 0);
- m_hThreadDone = CreateEvent(0, true, true, 0);
- m_bResult =false;
- m_lPieceLenExp = 0;
- m_hWnd = 0;
- }
- CMakeMetaFile::~CMakeMetaFile()
- {
- Close();
- assert(IsEventSet(m_hThreadDone));
- CloseHandle(m_hevDone);
- CloseHandle(m_hThreadDone);
- }
- /////////////////////////////////////////////////////////////////
- // return value : the state of making meta file.
- bool CMakeMetaFile::Close()
- {
- if (!IsEventSet(m_hThreadDone))
- {
- SetEvent(m_hevDone);
- DWORD dwRet = WaitForSingleObject(m_hThreadDone, INFINITE);
- switch (dwRet)
- {
- case WAIT_OBJECT_0:
- break;
- case WAIT_TIMEOUT:
- break;
- }
- }
- return m_bResult;
- }
- string CMakeMetaFile::GetSrcPath() const
- {
- return m_strFilePath;
- }
- string CMakeMetaFile::GetSavePath() const
- {
- return m_strSaveAs;
- }
- bool CMakeMetaFile::IsMaking()
- {
- return !IsEventSet(m_hThreadDone);
- }
- bool CMakeMetaFile::GetResult() const
- {
- return m_bResult;
- }
- string CMakeMetaFile::GetErrorMsg() const
- {
- return m_strErr;
- }
- bool CMakeMetaFile::MakeMetaFileEx(string strFilePath, string strSaveAs, string strUrl, string strComment, long lPieceLenExp, HWND hWnd)
- {
- // assert.
- assert(lPieceLenExp> 0 && lPieceLenExp< 25 &&
- !strFilePath.empty() &&
- !strSaveAs.empty() &&
- ::IsWindow(hWnd));
- m_strFilePath = strFilePath;
- m_strSaveAs = strSaveAs ;
- m_strUrl = strUrl;
- m_strComment = strComment;
- m_lPieceLenExp = lPieceLenExp;
- m_hWnd = hWnd;
- assert(::IsWindow(m_hWnd));
- m_bResult = false;
- m_strErr.erase();
- if (IsMaking())
- {
- assert(false);
- return false;
- }
- ResetEvent(m_hThreadDone);
- ResetEvent(m_hevDone);
- DWORD dwThreadId = 0;
- ::CreateThread(0, 0, MakeMetaFiledProc, this, 0, &dwThreadId);
- return true;
- }
- DWORD WINAPI CMakeMetaFile::MakeMetaFiledProc(void *pParam)
- {
- CMakeMetaFile* pMakeMetaFiled= (CMakeMetaFile* )pParam;
- pMakeMetaFiled->MakeMetaFiledProcEx();
- return 0;
- }
- void CMakeMetaFile::MakeMetaFiledProcEx()
- {
- m_bResult = MakeMetaFile();
- if (!IsEventSet(m_hevDone))
- PostMessage(m_hWnd, MAKE_METAFILE_FINISHED, 0, 0);
- SetEvent(m_hThreadDone);
- }
- bool CMakeMetaFile::MakeMetaFile()
- {
- // make info
- CVal* pInfo = makeinfo(m_strFilePath, pow(2, m_lPieceLenExp));
- if (!pInfo)
- {
- m_strErr += "makeinfo error";
- return false;
- }
- PVALMAP pMsg = new VALMAP();
- (*pMsg)["info"] = pInfo;
- (*pMsg)["announce"] = new CVal(m_strUrl);
- if (!m_strComment.empty())
- (*pMsg)["comment"] = new CVal(string(m_strComment));
- CVal* pValMsg = new CVal(pMsg);
- auto_ptr<CVal> aMsg(pValMsg);
- if (IsEventSet(m_hevDone))
- return false;
- // check info.
- try
- {
- CBTFormat::CheckInfo(pInfo);
- }
- catch (string e)
- {
- m_strErr += "check info error";
- return false;
- }
- // encode.
- memstream memBuf;
- CBdecode::bencode(pValMsg, memBuf);
- // save as torrent file.
- FILE* pfile = fopen(m_strSaveAs.data(), "wb");
- if (!pfile)
- {
- m_strErr = string("write torrent file (") + m_strSaveAs + ") error";
- return false;
- }
- long lWrite = fwrite(memBuf, sizeof(char), memBuf.size(), pfile);
- fclose(pfile);
- return true;
- }
- CVal* CMakeMetaFile::makeinfo(string strFilePath, long lPieceLength)
- {
- DWORD dwAttr = GetFileAttributes(strFilePath.data());
- if (dwAttr == 0xffffffff)
- return false;
- // get name map.
- if (strFilePath[strFilePath.size() - 1] == '\')
- strFilePath.erase(strFilePath.size() - 1);
- char *pszFileName = 0;
- char szPathName[MAX_PATH] = {0};
- if (!GetFullPathName(strFilePath.data(), MAX_PATH, szPathName, &pszFileName))
- {
- assert(false);
- return 0;
- }
- if (pszFileName == 0) // strFilePath is the root driver.
- {
- assert(false);
- return 0;
- }
- if (dwAttr & FILE_ATTRIBUTE_DIRECTORY)
- {
- // get vFiles.
- vector<string> vSubPaths;
- CSubFilesList SubFilesList;
- if (!SubFiles(strFilePath, vSubPaths, SubFilesList, m_hevDone))
- {
- for (int i=0; i<SubFilesList.size(); i++)
- {
- if (SubFilesList[i].m_pPathList)
- delete SubFilesList[i].m_pPathList;
- }
- return 0;
- }
- //
- // get pieces and files map.
- //
- int iPiecesCount = 0;
- memstream memPieces;
- PVALLIST pFileList = new VALLIST();
- long lDone = 0;
- long lTotalHashsed = 0;
- long lTotalSize = 0;
- for (int i=0; i<SubFilesList.size(); i++)
- {
- if (IsEventSet(m_hevDone))
- return 0;
- lTotalSize += GetFileSize(SubFilesList[i].m_strPath);
- }
- CSHA sha;
- sha.start();
- unsigned char sha1sum[20];
- for (i=0; i<SubFilesList.size(); i++)
- {
- FILE* pfile = fopen(SubFilesList[i].m_strPath.data(), "rb");
- if (!pfile)
- {
- m_strErr = "no such file : (" + SubFilesList[i].m_strPath + ")";
- break;
- }
- long lsize = GetFileSize(SubFilesList[i].m_strPath);
- long lPos = 0;
- unsigned char* pszBuf = new unsigned char[lPieceLength];
- auto_ptr<unsigned char> aszBuf(pszBuf);
- while (lPos < lsize)
- {
- long lLeftLen = min(lsize - lPos, lPieceLength - lDone);
- int iRead = fread(pszBuf, sizeof(char), lLeftLen, pfile);
- if (iRead != lLeftLen)
- {
- assert(false);
- fclose(pfile);
- break;
- }
- TRACE("Iseventset read in filern");
- if (IsEventSet(m_hevDone))
- break;
- lPos += iRead;
- lDone += iRead;
- lTotalHashsed += iRead;
- sha.update(pszBuf, lLeftLen);
- if (lDone == lPieceLength)
- {
- lDone = 0;
- sha.finish(sha1sum);
- memPieces.write((char*)sha1sum, 20);
- sha.start();
- iPiecesCount++;
- }
- if (lTotalSize > 0)
- ProgressInfo(float(lTotalHashsed)/ lTotalSize);
- else
- ProgressInfo(float(1));
- } // end while
- if (lPos < lsize)
- {
- // assert(false);
- fclose(pfile);
- break;
- }
- PVALMAP pFileMap = new VALMAP;
- (*pFileMap) ["length"] = new CVal(lsize);
- assert(SubFilesList[i].m_pPathList);
- (*pFileMap) ["path"] = SubFilesList[i].m_pPathList;
- SubFilesList[i].m_pPathList = 0;
- pFileList->push_back(new CVal(pFileMap));
- fclose(pfile);
- TRACE("Iseventset end for rn");
- if (IsEventSet(m_hevDone))
- break;
- } // end for
- if (i != SubFilesList.size()) // fail
- {
- delete new CVal(pFileList);
- // clear not detached pathlist CVal;
- for (int j=0; j<SubFilesList.size(); j++)
- {
- if (SubFilesList[j].m_pPathList)
- delete SubFilesList[j].m_pPathList;
- }
- return 0;
- }
- if (lDone > 0)
- {
- sha.finish(sha1sum);
- memPieces.write((char*)sha1sum, 20);
- iPiecesCount++;
- }
- PVALMAP pRet = new VALMAP();
- if (memPieces.size() <= 0)
- (*pRet)["pieces"] = new CVal(0, 0);
- else
- (*pRet)["pieces"] = new CVal(memPieces, memPieces.size());
- (*pRet)["piece length"] = new CVal(lPieceLength);
- (*pRet)["files"] = new CVal(pFileList);
- (*pRet)["name"] = new CVal(string(pszFileName));
- return new CVal(pRet);
- }
- else
- {
- long lsize = GetFileSize(strFilePath);
- FILE* pfile = fopen(strFilePath.data(), "rb");
- if (!pfile) return 0;
- memstream memPieces;
- CSHA sha;
- sha.start();
- unsigned char sha1sum[20];
- long lLeftLen = 0;
- long lPos = 0;
- unsigned char* pszBuf = new unsigned char[lPieceLength];
- auto_ptr<unsigned char> aszBuf(pszBuf);
- while (lPos < lsize)
- {
- lLeftLen = min(lsize - lPos, lPieceLength);
- int iRead = fread(pszBuf, sizeof(char), lLeftLen, pfile);
- if (iRead != lLeftLen)
- {
- assert(false);
- fclose(pfile);
- break;
- }
- if (IsEventSet(m_hevDone))
- break;
- lPos += iRead;
- sha.update(pszBuf, lLeftLen);
- sha.finish(sha1sum);
- memPieces.write((char*)sha1sum, 20);
- sha.start();
- if (lsize> 0)
- ProgressInfo(float(lPos)/ lsize);
- else
- ProgressInfo(float(1));
- }
- if (lPos < lsize) // fail
- {
- // assert(false);
- return 0;
- }
- fclose(pfile);
- PVALMAP pRet = new VALMAP();
- // (*pRet)["pieces"] = new CVal(memPieces, memPieces.size());
- if (memPieces.size() <= 0)
- (*pRet)["pieces"] = new CVal(0, 0);
- else
- (*pRet)["pieces"] = new CVal(memPieces, memPieces.size());
- (*pRet)["piece length"] = new CVal(lPieceLength);
- (*pRet)["length"] = new CVal(lsize);
- (*pRet)["name"] = new CVal(string(pszFileName));
- return new CVal(pRet);
- }
- return 0;
- }
- bool CMakeMetaFile::SubFiles(string strPath, vector<string> vSubPaths, CSubFilesList& SubFilesList, HANDLE hevDone)
- {
- DWORD dwAttr = GetFileAttributes(strPath.data());
- if (dwAttr == 0xffffffff)
- return false;
- WIN32_FIND_DATA FileData;
- BOOL fFinished = FALSE;
- if (strPath[strPath.size() - 1] != '\')
- strPath += '\';
- string strFind = strPath + "*.*";
- // TRACE("%srn", strPath.data());
- HANDLE hSearch = FindFirstFile(strFind.data(), &FileData);
- if (hSearch == INVALID_HANDLE_VALUE)
- return false;
- while (!fFinished)
- {
- if (string(FileData.cFileName) != "." &&
- string(FileData.cFileName) != ".." )
- {
- if (FileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
- {
- vector<string> vChildPaths = vSubPaths;
- vChildPaths.push_back(FileData.cFileName);
- if (!SubFiles(strPath + FileData.cFileName, vChildPaths, SubFilesList, hevDone))
- {
- FindClose(hSearch);
- return false;
- }
- }
- else
- {
- PVALLIST pvFileSubPath = new VALLIST();
- for (int i=0; i<vSubPaths.size(); i++)
- {
- (*pvFileSubPath).push_back(new CVal(vSubPaths[i]));
- }
- (*pvFileSubPath).push_back(new CVal(FileData.cFileName));
- SubFilesList.push_back(CSubFilesItem(new CVal(pvFileSubPath), strPath + FileData.cFileName));
- // TRACE("(%s)rn", FileData.cFileName);
- }
- }
- if (IsEventSet(hevDone))
- return false;
- if (!FindNextFile(hSearch, &FileData))
- {
- fFinished = TRUE;
- if (GetLastError() == ERROR_NO_MORE_FILES) { }
- else { }
- }
- }
- FindClose(hSearch);
- return true;
- }
- void CMakeMetaFile::ProgressInfo(float fPercent)
- {
- if (::IsWindow(m_hWnd))
- ::PostMessage(m_hWnd, MAKE_METAFILE_PROGRESS, fPercent*100, 0);
- }
- bool CMakeMetaFile::FormatSaveAS(string strFilePath, string& strToSavePath)
- {
- assert(!strToSavePath.empty() && !strFilePath.empty());
- string strName;
- if (!GetName(strFilePath, strName))
- return false;
- strToSavePath = formatDir(strToSavePath);
- strToSavePath += strName + ".torrent";
- return true;
- }
- bool CMakeMetaFile::GetName(string strFilePath, string& strName)
- {
- // get name map.
- if (strFilePath[strFilePath.size() - 1] == '\')
- strFilePath.erase(strFilePath.size() - 1);
- char *pszFileName = 0;
- char szPathName[MAX_PATH] = {0};
- if (!GetFullPathName(strFilePath.data(), MAX_PATH, szPathName, &pszFileName))
- {
- assert(false);
- return false;
- }
- if (pszFileName == 0) // strFilePath is the root driver.
- {
- assert(false);
- return 0;
- }
- strName = pszFileName;
- return true;
- }