mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-02-10 18:05:41 +08:00
Refactoring
This commit is contained in:
@ -1,165 +0,0 @@
|
||||
#ifndef _ZIPFOLDER_H_
|
||||
#define _ZIPFOLDER_H_
|
||||
|
||||
#include "./../../../../OfficeUtils/src/ZipBuffer.h"
|
||||
#include "./../../../common/File.h"
|
||||
#include "./../../../common/Directory.h"
|
||||
|
||||
class IZipFolder
|
||||
{
|
||||
public:
|
||||
virtual bool read (const std::wstring& path, BYTE*& data, DWORD& length) = 0;
|
||||
virtual void write (const std::wstring& path, BYTE* data, DWORD length) = 0;
|
||||
virtual void move (const std::wstring& sSrc, const std::wstring& sDst) = 0;
|
||||
virtual bool exists(const std::wstring& path) = 0;
|
||||
virtual void remove(const std::wstring& path) = 0;
|
||||
virtual void createDirectory(const std::wstring& path) = 0;
|
||||
virtual void writeZipFolder(BYTE*& data, DWORD& length) = 0;
|
||||
virtual void writeXml(const std::wstring& path, const std::wstring& xml) = 0;
|
||||
virtual std::vector<std::wstring> getFiles(const std::wstring& path, bool bIsRecursion) = 0;
|
||||
};
|
||||
|
||||
class CZipFolder : public IZipFolder
|
||||
{
|
||||
std::wstring m_sFolder;
|
||||
public:
|
||||
CZipFolder(const std::wstring& folder) : m_sFolder(folder) {}
|
||||
|
||||
virtual bool read (const std::wstring& path, BYTE*& data, DWORD& length)
|
||||
{
|
||||
if (NSFile::CFileBinary::Exists(path))
|
||||
return NSFile::CFileBinary::ReadAllBytes(path, &data, length);
|
||||
return false;
|
||||
}
|
||||
virtual void write (const std::wstring& path, BYTE* data, DWORD length)
|
||||
{
|
||||
NSFile::CFileBinary::Remove(path);
|
||||
NSFile::CFileBinary oFile;
|
||||
oFile.CreateFileW(path);
|
||||
oFile.WriteFile(data, length);
|
||||
oFile.CloseFile();
|
||||
}
|
||||
virtual void move (const std::wstring& sSrc, const std::wstring& sDst)
|
||||
{
|
||||
NSFile::CFileBinary::Move(sSrc, sDst);
|
||||
}
|
||||
virtual bool exists(const std::wstring& path)
|
||||
{
|
||||
return NSFile::CFileBinary::Exists(path);
|
||||
}
|
||||
virtual void remove(const std::wstring& path)
|
||||
{
|
||||
NSFile::CFileBinary::Remove(path);
|
||||
}
|
||||
virtual void createDirectory(const std::wstring& path)
|
||||
{
|
||||
if (!NSDirectory::Exists(path))
|
||||
NSDirectory::CreateDirectory(path);
|
||||
}
|
||||
virtual void writeZipFolder(BYTE*& data, DWORD& length)
|
||||
{
|
||||
}
|
||||
virtual void writeXml(const std::wstring& path, const std::wstring& xml)
|
||||
{
|
||||
std::string sXmlUtf8 = U_TO_UTF8(xml);
|
||||
write(path, (BYTE*)sXmlUtf8.c_str(), (DWORD)sXmlUtf8.length());
|
||||
}
|
||||
virtual std::vector<std::wstring> getFiles(const std::wstring& path, bool bIsRecursion)
|
||||
{
|
||||
return NSDirectory::GetFiles(path, bIsRecursion);
|
||||
}
|
||||
};
|
||||
|
||||
class CZipFolderMemory : public IZipFolder
|
||||
{
|
||||
CZipBuffer* m_zlib;
|
||||
public:
|
||||
CZipFolderMemory(BYTE* data, DWORD length)
|
||||
{
|
||||
m_zlib = new CZipBuffer(data, length);
|
||||
}
|
||||
std::string normalPath(const std::wstring& path)
|
||||
{
|
||||
if (!path.empty() && path[0] == L'/')
|
||||
return U_TO_UTF8(path.substr(1));
|
||||
return U_TO_UTF8(path);
|
||||
}
|
||||
|
||||
virtual bool read (const std::wstring& path, BYTE*& data, DWORD& length)
|
||||
{
|
||||
std::string sPath = normalPath(path);
|
||||
m_zlib->getFile(sPath, data, length);
|
||||
if (length)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
virtual void write (const std::wstring& path, BYTE* data, DWORD length)
|
||||
{
|
||||
std::string sPath = normalPath(path);
|
||||
BYTE* copyData = new BYTE[length];
|
||||
memcpy(copyData, data, length);
|
||||
m_zlib->addFile(sPath, copyData, length);
|
||||
}
|
||||
virtual void move (const std::wstring& sSrc, const std::wstring& sDst)
|
||||
{
|
||||
std::string sSrcPath = normalPath(sSrc);
|
||||
BYTE* data; DWORD length;
|
||||
m_zlib->getFile(sSrcPath, data, length);
|
||||
BYTE* copyData = new BYTE[length];
|
||||
memcpy(copyData, data, length);
|
||||
m_zlib->removeFile(sSrcPath);
|
||||
m_zlib->addFile(normalPath(sDst), copyData, length);
|
||||
}
|
||||
virtual bool exists(const std::wstring& path)
|
||||
{
|
||||
std::string sPath = normalPath(path);
|
||||
std::vector<std::string> sPaths = m_zlib->getPaths();
|
||||
return std::find(sPaths.begin(), sPaths.end(), sPath) != sPaths.end();
|
||||
}
|
||||
virtual void remove(const std::wstring& path)
|
||||
{
|
||||
std::string sPath = normalPath(path);
|
||||
m_zlib->removeFile(sPath);
|
||||
}
|
||||
virtual void createDirectory(const std::wstring& path)
|
||||
{
|
||||
}
|
||||
virtual void writeZipFolder(BYTE*& data, DWORD& length)
|
||||
{
|
||||
m_zlib->save(data, length);
|
||||
m_zlib->close();
|
||||
}
|
||||
virtual void writeXml(const std::wstring& path, const std::wstring& xml)
|
||||
{
|
||||
std::string sXmlUtf8 = U_TO_UTF8(xml);
|
||||
write(path, (BYTE*)sXmlUtf8.c_str(), (DWORD)sXmlUtf8.length());
|
||||
}
|
||||
virtual std::vector<std::wstring> getFiles(const std::wstring& path, bool bIsRecursion)
|
||||
{
|
||||
std::string sPath = normalPath(path);
|
||||
std::vector<std::string> sPaths = m_zlib->getPaths();
|
||||
std::vector<std::wstring> sRes;
|
||||
|
||||
for (std::string& i : sPaths)
|
||||
{
|
||||
if (bIsRecursion)
|
||||
{
|
||||
if (i.find(sPath) == 0)
|
||||
sRes.push_back(L'/' + UTF8_TO_U(i));
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t nFindDirectory = i.find(sPath);
|
||||
if (nFindDirectory == 0)
|
||||
{
|
||||
nFindDirectory = i.find_first_of("\\/", sPath.length());
|
||||
if (nFindDirectory != std::wstring::npos && i.find_first_of("\\/", nFindDirectory + 1) == std::wstring::npos)
|
||||
sRes.push_back(L'/' + UTF8_TO_U(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
return sRes;
|
||||
}
|
||||
};
|
||||
|
||||
#endif //_ZIPFOLDER_H_
|
||||
@ -1,6 +1,6 @@
|
||||
#include "./../include/OOXMLSigner.h"
|
||||
#include "./../include/ZipFolder.h"
|
||||
#include "./../src/XmlTransform.h"
|
||||
#include "./ZipFolder.h"
|
||||
#include "./XmlTransform.h"
|
||||
#include <cstdio>
|
||||
#include <ctime>
|
||||
#include <time.h>
|
||||
@ -9,8 +9,7 @@ class COOXMLSigner_private
|
||||
{
|
||||
public:
|
||||
ICertificate* m_certificate;
|
||||
IZipFolder* m_pZipFolder;
|
||||
std::wstring m_sFolder;
|
||||
IFolder* m_pFolder;
|
||||
|
||||
std::wstring m_date;
|
||||
|
||||
@ -28,37 +27,21 @@ public:
|
||||
public:
|
||||
COOXMLSigner_private(const std::wstring& sFolder, ICertificate* pContext)
|
||||
{
|
||||
m_sFolder = sFolder;
|
||||
m_pZipFolder = new CZipFolder(sFolder);
|
||||
m_pFolder = new CFolderSystem(sFolder);
|
||||
m_certificate = pContext;
|
||||
|
||||
m_date = L"2017-04-21T08:30:21Z";
|
||||
|
||||
std::time_t rawtime;
|
||||
std::tm* timeinfo;
|
||||
char buffer1[100];
|
||||
char buffer2[100];
|
||||
|
||||
std::time(&rawtime);
|
||||
timeinfo = std::gmtime(&rawtime);
|
||||
|
||||
std::strftime(buffer1, 100, "%Y-%m-%d", timeinfo);
|
||||
std::strftime(buffer2, 100, "%H:%M:%S", timeinfo);
|
||||
|
||||
std::string date = (std::string(buffer1) + "T" + std::string(buffer2) + "Z");
|
||||
m_date = NSFile::CUtf8Converter::GetUnicodeFromCharPtr(date);
|
||||
|
||||
m_signed_info.WriteString("<CanonicalizationMethod Algorithm=\"http://www.w3.org/TR/2001/REC-xml-c14n-20010315\"/>");
|
||||
m_signed_info.WriteString("<SignatureMethod Algorithm=\"");
|
||||
m_signed_info.WriteString(ICertificate::GetSignatureMethodA(m_certificate->GetHashAlg()));
|
||||
m_signed_info.WriteString("\"/>");
|
||||
OpenFolder();
|
||||
}
|
||||
COOXMLSigner_private(BYTE* data, DWORD length, ICertificate* pContext)
|
||||
{
|
||||
m_sFolder = L"";
|
||||
m_pZipFolder = new CZipFolderMemory(data, length);
|
||||
m_pFolder = new CZipFolderMemory(data, length);
|
||||
m_certificate = pContext;
|
||||
|
||||
OpenFolder();
|
||||
}
|
||||
|
||||
void OpenFolder()
|
||||
{
|
||||
m_date = L"2017-04-21T08:30:21Z";
|
||||
|
||||
std::time_t rawtime;
|
||||
@ -80,22 +63,18 @@ public:
|
||||
m_signed_info.WriteString(ICertificate::GetSignatureMethodA(m_certificate->GetHashAlg()));
|
||||
m_signed_info.WriteString("\"/>");
|
||||
}
|
||||
|
||||
~COOXMLSigner_private()
|
||||
{
|
||||
RELEASEOBJECT(m_pFolder);
|
||||
}
|
||||
|
||||
std::wstring GetReference(const std::wstring& file, const std::wstring& content_type)
|
||||
{
|
||||
std::wstring sXml = L"<Reference URI=\"" + file + L"?ContentType=" + content_type + L"\">";
|
||||
std::wstring sXml = L"<Reference URI=\"/" + file + L"?ContentType=" + content_type + L"\">";
|
||||
sXml += (L"<DigestMethod Algorithm=\"" + ICertificate::GetDigestMethod(m_certificate->GetHashAlg()) + L"\"/>");
|
||||
sXml += L"<DigestValue>";
|
||||
|
||||
BYTE* pData = NULL;
|
||||
DWORD dwLen = 0;
|
||||
m_pZipFolder->read(m_sFolder + file, pData, dwLen);
|
||||
std::string sTmp = m_certificate->GetHash(pData, dwLen, m_certificate->GetHashAlg());
|
||||
|
||||
sXml += UTF8_TO_U(sTmp);
|
||||
sXml += m_pFolder->getFileHashW(file, m_certificate);
|
||||
sXml += L"</DigestValue>";
|
||||
sXml += L"</Reference>";
|
||||
return sXml;
|
||||
@ -136,21 +115,8 @@ public:
|
||||
return file.substr(file.find(L",") + 1);
|
||||
}
|
||||
|
||||
BYTE* pData = NULL;
|
||||
DWORD dwLen = 0;
|
||||
if (!m_pZipFolder->read(file, pData, dwLen))
|
||||
return L"";
|
||||
|
||||
char* pDataC = NULL;
|
||||
int nLen = 0;
|
||||
NSFile::CBase64Converter::Encode(pData, (int)dwLen, pDataC, nLen, NSBase64::B64_BASE64_FLAG_NOCRLF);
|
||||
|
||||
std::wstring sReturn = NSFile::CUtf8Converter::GetUnicodeFromCharPtr(pDataC, (LONG)nLen, FALSE);
|
||||
|
||||
RELEASEARRAYOBJECTS(pData);
|
||||
RELEASEARRAYOBJECTS(pDataC);
|
||||
|
||||
return sReturn;
|
||||
std::string sRet = m_pFolder->getFileBase64(file);
|
||||
return UTF8_TO_U(sRet);
|
||||
}
|
||||
std::wstring GetImageBase64(BYTE* data, DWORD length)
|
||||
{
|
||||
@ -167,23 +133,13 @@ public:
|
||||
|
||||
std::wstring GetRelsReference(const std::wstring& file)
|
||||
{
|
||||
BYTE* pData = NULL;
|
||||
DWORD dwLen = 0;
|
||||
if (!m_pZipFolder->read(m_sFolder + file, pData, dwLen))
|
||||
return L"";
|
||||
|
||||
COOXMLRelationships oRels(NSFile::CUtf8Converter::GetUnicodeStringFromUTF8(pData, dwLen), false);
|
||||
COOXMLRelationships oRels(file, m_pFolder);
|
||||
if (oRels.rels.size() == 0)
|
||||
return L"";
|
||||
|
||||
if (L"/_rels/.rels" == file)
|
||||
if (L"_rels/.rels" == file)
|
||||
{
|
||||
BYTE* pDataNew = new BYTE[dwLen];
|
||||
memcpy(pDataNew, pData, dwLen);
|
||||
long nLength = dwLen;
|
||||
oRels.CheckOriginSigs(pDataNew, nLength);
|
||||
m_pZipFolder->write(m_sFolder + file, pDataNew, nLength);
|
||||
RELEASEARRAYOBJECTS(pDataNew);
|
||||
oRels.CheckOriginSigs(file);
|
||||
|
||||
// удалим все лишнее
|
||||
std::vector<COOXMLRelationship>::iterator i = oRels.rels.begin();
|
||||
@ -199,7 +155,7 @@ public:
|
||||
}
|
||||
|
||||
NSStringUtils::CStringBuilder builder;
|
||||
builder.WriteString(L"<Reference URI=\"");
|
||||
builder.WriteString(L"<Reference URI=\"/");
|
||||
builder.WriteString(file);
|
||||
builder.WriteString(L"?ContentType=application/vnd.openxmlformats-package.relationships+xml\">");
|
||||
builder.WriteString(oRels.GetTransforms());
|
||||
@ -220,17 +176,13 @@ public:
|
||||
{
|
||||
std::wstring sRelsFolder = folder + L"/_rels";
|
||||
|
||||
std::vector<std::wstring> arFiles = m_pZipFolder->getFiles(sRelsFolder, false);
|
||||
std::vector<std::wstring> arFiles = m_pFolder->getFiles(sRelsFolder, false);
|
||||
std::map<std::wstring, bool> arSigFiles;
|
||||
|
||||
for (std::vector<std::wstring>::iterator iter = arFiles.begin(); iter != arFiles.end(); iter++)
|
||||
{
|
||||
BYTE* pData = NULL;
|
||||
DWORD dwLen = 0;
|
||||
m_pZipFolder->read(*iter, pData, dwLen);
|
||||
|
||||
XmlUtils::CXmlNode oNodeRels;
|
||||
if (!oNodeRels.FromXmlString(NSFile::CUtf8Converter::GetUnicodeStringFromUTF8(pData, dwLen)))
|
||||
XmlUtils::CXmlNode oNodeRels = m_pFolder->getNodeFromFile(*iter);
|
||||
if (!oNodeRels.IsValid())
|
||||
continue;
|
||||
XmlUtils::CXmlNodes oNodesRels = oNodeRels.GetNodes(L"Relationship");
|
||||
int nCount = oNodesRels.GetCount();
|
||||
@ -240,10 +192,10 @@ public:
|
||||
oNodesRels.GetAt(nIndex, oNodeRel);
|
||||
|
||||
std::wstring sTarget = oNodeRel.GetAttribute(L"Target");
|
||||
if (!sTarget.empty() && arSigFiles.find(sTarget) == arSigFiles.end() && m_pZipFolder->exists(folder + L"/" + sTarget))
|
||||
if (!sTarget.empty() && arSigFiles.find(sTarget) == arSigFiles.end() && m_pFolder->exists(folder + L"/" + sTarget))
|
||||
arSigFiles.insert(std::pair<std::wstring, bool>(sTarget, true));
|
||||
}
|
||||
m_pZipFolder->remove(*iter);
|
||||
m_pFolder->remove(*iter);
|
||||
}
|
||||
|
||||
int nCountSigs = (int)arSigFiles.size();
|
||||
@ -263,13 +215,13 @@ public:
|
||||
|
||||
oBuilder.WriteString(L"</Relationships>");
|
||||
|
||||
m_pZipFolder->writeXml(sFile, oBuilder.GetData());
|
||||
m_pFolder->writeXml(sFile, oBuilder.GetData());
|
||||
|
||||
// теперь перебьем все имена файлов
|
||||
|
||||
std::vector<std::wstring> arSigs;
|
||||
|
||||
std::vector<std::wstring> arFilesXml = m_pZipFolder->getFiles(folder, false);
|
||||
std::vector<std::wstring> arFilesXml = m_pFolder->getFiles(folder, false);
|
||||
for (std::vector<std::wstring>::iterator iter = arFilesXml.begin(); iter != arFilesXml.end(); iter++)
|
||||
{
|
||||
std::wstring sXmlFileName = NSFile::GetFileName(*iter);
|
||||
@ -280,7 +232,7 @@ public:
|
||||
if (find == arSigFiles.end())
|
||||
{
|
||||
// ненужная xml
|
||||
m_pZipFolder->remove(*iter);
|
||||
m_pFolder->remove(*iter);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -290,12 +242,12 @@ public:
|
||||
std::sort(arSigs.begin(), arSigs.end());
|
||||
for (std::vector<std::wstring>::iterator iter = arSigs.begin(); iter != arSigs.end(); iter++)
|
||||
{
|
||||
m_pZipFolder->move(folder + L"/" + *iter, folder + L"/onlyoffice_" + *iter);
|
||||
m_pFolder->move(folder + L"/" + *iter, folder + L"/onlyoffice_" + *iter);
|
||||
}
|
||||
int nSigNumber = 1;
|
||||
for (std::vector<std::wstring>::iterator iter = arSigs.begin(); iter != arSigs.end(); iter++)
|
||||
{
|
||||
m_pZipFolder->move(folder + L"/onlyoffice_" + *iter, folder + L"/sig" + std::to_wstring(nSigNumber++) + L".xml");
|
||||
m_pFolder->move(folder + L"/onlyoffice_" + *iter, folder + L"/sig" + std::to_wstring(nSigNumber++) + L".xml");
|
||||
}
|
||||
|
||||
return (int)arSigs.size();
|
||||
@ -303,14 +255,7 @@ public:
|
||||
|
||||
void ParseContentTypes()
|
||||
{
|
||||
std::wstring file = m_sFolder + L"/[Content_Types].xml";
|
||||
|
||||
BYTE* pData = NULL;
|
||||
DWORD dwLen = 0;
|
||||
m_pZipFolder->read(file, pData, dwLen);
|
||||
|
||||
XmlUtils::CXmlNode oNode;
|
||||
oNode.FromXmlString(NSFile::CUtf8Converter::GetUnicodeStringFromUTF8(pData, dwLen));
|
||||
XmlUtils::CXmlNode oNode = m_pFolder->getNodeFromFile(L"/[Content_Types].xml");
|
||||
|
||||
XmlUtils::CXmlNodes nodesDefaults;
|
||||
oNode.GetNodes(L"Default", nodesDefaults);
|
||||
@ -343,27 +288,22 @@ public:
|
||||
ParseContentTypes();
|
||||
|
||||
// 2) Parse files in directory
|
||||
std::vector<std::wstring> files = m_pZipFolder->getFiles(m_sFolder, true);
|
||||
std::vector<std::wstring> files = m_pFolder->getFiles(L"", true);
|
||||
|
||||
// 3) Check each file
|
||||
std::wstring sFolder = m_sFolder;
|
||||
NSStringUtils::string_replace(sFolder, L"\\", L"/");
|
||||
std::wstring sFolder = L"";
|
||||
for (std::vector<std::wstring>::iterator i = files.begin(); i != files.end(); i++)
|
||||
{
|
||||
std::wstring sCheckFile = *i;
|
||||
NSStringUtils::string_replace(sCheckFile, L"\\", L"/");
|
||||
|
||||
if (0 != sCheckFile.find(sFolder))
|
||||
continue;
|
||||
|
||||
// make cool filename
|
||||
sCheckFile = sCheckFile.substr(sFolder.length());
|
||||
sCheckFile = m_pFolder->getLocalFilePath(sCheckFile);
|
||||
|
||||
// check needed file
|
||||
if (0 == sCheckFile.find(L"/_xmlsignatures") ||
|
||||
0 == sCheckFile.find(L"/docProps") ||
|
||||
0 == sCheckFile.find(L"/[Content_Types].xml") ||
|
||||
0 == sCheckFile.find(L"/[trash]"))
|
||||
if (0 == sCheckFile.find(L"_xmlsignatures") ||
|
||||
0 == sCheckFile.find(L"docProps") ||
|
||||
0 == sCheckFile.find(L"[Content_Types].xml") ||
|
||||
0 == sCheckFile.find(L"[trash]"))
|
||||
continue;
|
||||
|
||||
// check rels and add to needed array
|
||||
@ -429,14 +369,8 @@ public:
|
||||
|
||||
void CorrectContentTypes(int nCountSignatures)
|
||||
{
|
||||
std::wstring file = m_sFolder + L"/[Content_Types].xml";
|
||||
|
||||
BYTE* pData = NULL;
|
||||
DWORD dwLen = 0;
|
||||
m_pZipFolder->read(file, pData, dwLen);
|
||||
|
||||
XmlUtils::CXmlNode oNode;
|
||||
oNode.FromXmlString(NSFile::CUtf8Converter::GetUnicodeStringFromUTF8(pData, dwLen));
|
||||
std::wstring file = L"[Content_Types].xml";
|
||||
XmlUtils::CXmlNode oNode = m_pFolder->getNodeFromFile(file);
|
||||
|
||||
NSStringUtils::CStringBuilder oBuilder;
|
||||
oBuilder.WriteString(L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>");
|
||||
@ -483,7 +417,7 @@ public:
|
||||
|
||||
oBuilder.WriteNodeEnd(oNode.GetName());
|
||||
|
||||
m_pZipFolder->writeXml(file, oBuilder.GetData());
|
||||
m_pFolder->writeXml(file, oBuilder.GetData());
|
||||
}
|
||||
|
||||
void SetGuid(const std::wstring& guid)
|
||||
@ -654,25 +588,25 @@ public:
|
||||
|
||||
int AddSignatureReference()
|
||||
{
|
||||
std::wstring sDirectory = m_sFolder + L"/_xmlsignatures";
|
||||
std::wstring sDirectory = L"/_xmlsignatures";
|
||||
|
||||
m_pZipFolder->createDirectory(sDirectory);
|
||||
m_pFolder->createDirectory(sDirectory);
|
||||
|
||||
// remove old .sig file
|
||||
std::vector<std::wstring> arFiles = m_pZipFolder->getFiles(sDirectory, false);
|
||||
std::vector<std::wstring> arFiles = m_pFolder->getFiles(sDirectory, false);
|
||||
for (std::vector<std::wstring>::iterator i = arFiles.begin(); i != arFiles.end(); i++)
|
||||
{
|
||||
if (NSFile::GetFileExtention(*i) == L"sigs")
|
||||
{
|
||||
m_pZipFolder->remove(*i);
|
||||
m_pFolder->remove(*i);
|
||||
}
|
||||
}
|
||||
|
||||
std::wstring sOriginName = L"origin.sigs";
|
||||
if (!m_pZipFolder->exists(sDirectory + L"/" + sOriginName))
|
||||
m_pZipFolder->write(sDirectory + L"/" + sOriginName, NULL, 0);
|
||||
if (!m_pFolder->exists(sDirectory + L"/" + sOriginName))
|
||||
m_pFolder->write(sDirectory + L"/" + sOriginName, NULL, 0);
|
||||
|
||||
m_pZipFolder->createDirectory(sDirectory + L"/_rels");
|
||||
m_pFolder->createDirectory(sDirectory + L"/_rels");
|
||||
|
||||
int nSignNum = GetCountSigns(sDirectory);
|
||||
|
||||
@ -714,9 +648,17 @@ public:
|
||||
|
||||
int nSignNum = AddSignatureReference();
|
||||
|
||||
m_pZipFolder->writeXml(m_sFolder + L"/_xmlsignatures/sig" + std::to_wstring(nSignNum + 1) + L".xml", builderResult.GetData());
|
||||
m_pFolder->writeXml(L"_xmlsignatures/sig" + std::to_wstring(nSignNum + 1) + L".xml", builderResult.GetData());
|
||||
|
||||
IFolder::CBuffer* buffer = m_pFolder->finalize();
|
||||
if (buffer)
|
||||
{
|
||||
pFiletoWrite = buffer->Buffer;
|
||||
dwLenFiletoWrite = buffer->Size;
|
||||
buffer->UnsetDestroy();
|
||||
delete buffer;
|
||||
}
|
||||
|
||||
m_pZipFolder->writeZipFolder(pFiletoWrite, dwLenFiletoWrite);
|
||||
return (sSignedXml.empty()) ? 1 : 0;
|
||||
}
|
||||
};
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
#include "./XmlTransform.h"
|
||||
#include "./../include/OOXMLVerifier.h"
|
||||
#include "./../include/ZipFolder.h"
|
||||
#include "./ZipFolder.h"
|
||||
|
||||
class COOXMLSignature_private
|
||||
{
|
||||
@ -13,7 +13,7 @@ public:
|
||||
std::string m_sImageInvalidBase64;
|
||||
|
||||
std::wstring m_sFolder;
|
||||
IZipFolder* m_pZipFolder;
|
||||
IFolder* m_pFolder;
|
||||
|
||||
std::wstring m_sFile;
|
||||
std::string m_sDate;
|
||||
@ -401,7 +401,7 @@ public:
|
||||
sFile = sFile.substr(0, nPos);
|
||||
sFile = m_sFolder + sFile;
|
||||
|
||||
if (!m_pZipFolder->exists(sFile))
|
||||
if (!m_pFolder->exists(sFile))
|
||||
return OOXML_SIGNATURE_INVALID;
|
||||
|
||||
XmlUtils::CXmlNode nodeMethod = node.ReadNode(L"DigestMethod");
|
||||
@ -422,11 +422,7 @@ public:
|
||||
if (!nodeTransform.IsValid())
|
||||
{
|
||||
// simple hash
|
||||
BYTE* pData = NULL;
|
||||
DWORD dwLen = 0;
|
||||
m_pZipFolder->read(sFile, pData, dwLen);
|
||||
|
||||
sCalcValue = m_cert->GetHash(pData, dwLen, nAlg);
|
||||
sCalcValue = m_pFolder->getFileHash(sFile, m_cert, nAlg);
|
||||
sValue = U_TO_UTF8((node.ReadNodeText(L"DigestValue")));
|
||||
MakeBase64_NOCRLF(sValue);
|
||||
}
|
||||
@ -437,10 +433,8 @@ public:
|
||||
if (!oTransforms.GetValid())
|
||||
return OOXML_SIGNATURE_NOTSUPPORTED;
|
||||
|
||||
BYTE* pData = NULL;
|
||||
DWORD dwLen = 0;
|
||||
m_pZipFolder->read(sFile, pData, dwLen);
|
||||
std::string sXml = oTransforms.Transform(std::string((char*)pData, dwLen));
|
||||
std::string sXml = m_pFolder->readXml(sFile);
|
||||
sXml = oTransforms.Transform(sXml);
|
||||
|
||||
sCalcValue = m_cert->GetHash(sXml, nAlg);
|
||||
sValue = U_TO_UTF8((node.ReadNodeText(L"DigestValue")));
|
||||
@ -565,81 +559,26 @@ void COOXMLSignature::Check()
|
||||
class COOXMLVerifier_private
|
||||
{
|
||||
public:
|
||||
std::wstring m_sFolder;
|
||||
IZipFolder* m_pZipFolder;
|
||||
IFolder* m_pFolder;
|
||||
std::vector<COOXMLSignature*> m_arSignatures;
|
||||
std::vector<std::wstring> m_arSignaturesFiles;
|
||||
|
||||
public:
|
||||
COOXMLVerifier_private(const std::wstring& sFolder)
|
||||
{
|
||||
m_sFolder = sFolder;
|
||||
m_pZipFolder = new CZipFolder(sFolder);
|
||||
|
||||
// check .sig file
|
||||
std::vector<std::wstring> arFiles = m_pZipFolder->getFiles(m_sFolder + L"/_xmlsignatures", false);
|
||||
bool bIsFound = false;
|
||||
for (std::vector<std::wstring>::iterator i = arFiles.begin(); i != arFiles.end(); i++)
|
||||
{
|
||||
if (NSFile::GetFileExtention(*i) == L"sigs")
|
||||
{
|
||||
bIsFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bIsFound)
|
||||
return;
|
||||
|
||||
BYTE* pData = NULL;
|
||||
DWORD dwLen = 0;
|
||||
m_pZipFolder->read(m_sFolder + L"/[Content_Types].xml", pData, dwLen);
|
||||
|
||||
XmlUtils::CXmlNode oContentTypes;
|
||||
if (!oContentTypes.FromXmlString(NSFile::CUtf8Converter::GetUnicodeStringFromUTF8(pData, dwLen)))
|
||||
return;
|
||||
|
||||
XmlUtils::CXmlNodes oOverrides = oContentTypes.GetNodes(L"Override");
|
||||
int nCount = oOverrides.GetCount();
|
||||
|
||||
for (int i = 0; i < nCount; i++)
|
||||
{
|
||||
XmlUtils::CXmlNode node;
|
||||
oOverrides.GetAt(i, node);
|
||||
|
||||
if (node.GetAttributeA("ContentType") != "application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml")
|
||||
continue;
|
||||
|
||||
std::wstring sFile = m_sFolder + node.GetAttribute("PartName");
|
||||
BYTE* pData = NULL;
|
||||
DWORD dwLen = 0;
|
||||
m_pZipFolder->read(sFile, pData, dwLen);
|
||||
|
||||
XmlUtils::CXmlNode nodeSig;
|
||||
if (!nodeSig.FromXmlString(NSFile::CUtf8Converter::GetUnicodeStringFromUTF8(pData, dwLen)))
|
||||
continue;
|
||||
|
||||
if (nodeSig.GetName() != L"Signature")
|
||||
continue;
|
||||
|
||||
COOXMLSignature* pSignature = new COOXMLSignature();
|
||||
pSignature->m_internal->m_sFile = sFile;
|
||||
pSignature->m_internal->m_node = nodeSig;
|
||||
pSignature->m_internal->m_sFolder = m_sFolder;
|
||||
pSignature->m_internal->m_pZipFolder = m_pZipFolder;
|
||||
pSignature->Check();
|
||||
|
||||
m_arSignatures.push_back(pSignature);
|
||||
m_arSignaturesFiles.push_back(sFile);
|
||||
}
|
||||
m_pFolder = new CFolderSystem(sFolder);
|
||||
OpenFolder();
|
||||
}
|
||||
COOXMLVerifier_private(BYTE* data, DWORD length)
|
||||
{
|
||||
m_sFolder = L"";
|
||||
m_pZipFolder = new CZipFolderMemory(data, length);
|
||||
m_pFolder = new CZipFolderMemory(data, length);
|
||||
OpenFolder();
|
||||
}
|
||||
|
||||
void OpenFolder()
|
||||
{
|
||||
// check .sig file
|
||||
std::vector<std::wstring> arFiles = m_pZipFolder->getFiles(m_sFolder + L"/_xmlsignatures", false);
|
||||
std::vector<std::wstring> arFiles = m_pFolder->getFiles(L"_xmlsignatures", false);
|
||||
bool bIsFound = false;
|
||||
for (std::vector<std::wstring>::iterator i = arFiles.begin(); i != arFiles.end(); i++)
|
||||
{
|
||||
@ -653,12 +592,8 @@ public:
|
||||
if (!bIsFound)
|
||||
return;
|
||||
|
||||
BYTE* pData = NULL;
|
||||
DWORD dwLen = 0;
|
||||
m_pZipFolder->read(m_sFolder + L"/[Content_Types].xml", pData, dwLen);
|
||||
|
||||
XmlUtils::CXmlNode oContentTypes;
|
||||
if (!oContentTypes.FromXmlString(NSFile::CUtf8Converter::GetUnicodeStringFromUTF8(pData, dwLen)))
|
||||
XmlUtils::CXmlNode oContentTypes = m_pFolder->getNodeFromFile(L"[Content_Types].xml");
|
||||
if (!oContentTypes.IsValid())
|
||||
return;
|
||||
|
||||
XmlUtils::CXmlNodes oOverrides = oContentTypes.GetNodes(L"Override");
|
||||
@ -672,13 +607,9 @@ public:
|
||||
if (node.GetAttributeA("ContentType") != "application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml")
|
||||
continue;
|
||||
|
||||
std::wstring sFile = m_sFolder + node.GetAttribute("PartName");
|
||||
BYTE* pData = NULL;
|
||||
DWORD dwLen = 0;
|
||||
m_pZipFolder->read(sFile, pData, dwLen);
|
||||
|
||||
XmlUtils::CXmlNode nodeSig;
|
||||
if (!nodeSig.FromXmlString(NSFile::CUtf8Converter::GetUnicodeStringFromUTF8(pData, dwLen)))
|
||||
std::wstring sFile = node.GetAttribute("PartName");
|
||||
XmlUtils::CXmlNode nodeSig = m_pFolder->getNodeFromFile(sFile);
|
||||
if (!nodeSig.IsValid())
|
||||
continue;
|
||||
|
||||
if (nodeSig.GetName() != L"Signature")
|
||||
@ -687,14 +618,14 @@ public:
|
||||
COOXMLSignature* pSignature = new COOXMLSignature();
|
||||
pSignature->m_internal->m_sFile = sFile;
|
||||
pSignature->m_internal->m_node = nodeSig;
|
||||
pSignature->m_internal->m_sFolder = m_sFolder;
|
||||
pSignature->m_internal->m_pZipFolder = m_pZipFolder;
|
||||
pSignature->m_internal->m_pFolder = m_pFolder;
|
||||
pSignature->Check();
|
||||
|
||||
m_arSignatures.push_back(pSignature);
|
||||
m_arSignaturesFiles.push_back(sFile);
|
||||
}
|
||||
}
|
||||
|
||||
~COOXMLVerifier_private()
|
||||
{
|
||||
for (std::vector<COOXMLSignature*>::iterator i = m_arSignatures.begin(); i != m_arSignatures.end(); i++)
|
||||
@ -703,6 +634,7 @@ public:
|
||||
RELEASEOBJECT(v);
|
||||
}
|
||||
m_arSignatures.clear();
|
||||
RELEASEOBJECT(m_pFolder);
|
||||
}
|
||||
|
||||
void RemoveSignature(const std::string& sGuid)
|
||||
@ -733,19 +665,12 @@ public:
|
||||
}
|
||||
|
||||
if (!sFile.empty())
|
||||
m_pZipFolder->remove(sFile);
|
||||
m_pFolder->remove(sFile);
|
||||
|
||||
if (!bIsRemoveAll && sFile.empty())
|
||||
return;
|
||||
|
||||
BYTE* pData = NULL;
|
||||
DWORD dwLen = 0;
|
||||
m_pZipFolder->read(m_sFolder + L"/[Content_Types].xml", pData, dwLen);
|
||||
|
||||
XmlUtils::CXmlNode oContentTypes;
|
||||
if (!oContentTypes.FromXmlString(NSFile::CUtf8Converter::GetUnicodeStringFromUTF8(pData, dwLen)))
|
||||
return;
|
||||
|
||||
XmlUtils::CXmlNode oContentTypes = m_pFolder->getNodeFromFile(L"[Content_Types].xml");
|
||||
std::wstring sXml = L"<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">";
|
||||
XmlUtils::CXmlNodes oNodes;
|
||||
if (oContentTypes.GetNodes(L"*", oNodes))
|
||||
@ -768,7 +693,7 @@ public:
|
||||
}
|
||||
else
|
||||
{
|
||||
std::wstring sFileFound = sFile.substr(m_sFolder.length());
|
||||
std::wstring sFileFound = m_pFolder->getLocalFilePath(sFile);
|
||||
if (L"Override" == oNode.GetName() &&
|
||||
L"application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml" == oNode.GetAttribute(L"ContentType") &&
|
||||
sFileFound == oNode.GetAttribute(L"PartName"))
|
||||
@ -780,20 +705,16 @@ public:
|
||||
}
|
||||
sXml += L"</Types>";
|
||||
|
||||
m_pZipFolder->writeXml(m_sFolder + L"/[Content_Types].xml", sXml);
|
||||
m_pFolder->writeXml(L"[Content_Types].xml", sXml);
|
||||
|
||||
if (bIsRemoveAll)
|
||||
{
|
||||
std::vector<std::wstring> arrDeleteFiles = m_pZipFolder->getFiles(m_sFolder + L"/_xmlsignatures", true);
|
||||
std::vector<std::wstring> arrDeleteFiles = m_pFolder->getFiles(L"_xmlsignatures", true);
|
||||
for (const std::wstring& sPath : arrDeleteFiles)
|
||||
m_pZipFolder->remove(sPath);
|
||||
m_pFolder->remove(sPath);
|
||||
|
||||
BYTE* pData = NULL;
|
||||
DWORD dwLen = 0;
|
||||
m_pZipFolder->read(m_sFolder + L"/_rels/.rels", pData, dwLen);
|
||||
|
||||
XmlUtils::CXmlNode oRels;
|
||||
if (!oRels.FromXmlString(NSFile::CUtf8Converter::GetUnicodeStringFromUTF8(pData, dwLen)))
|
||||
XmlUtils::CXmlNode oRels = m_pFolder->getNodeFromFile(L"_rels/.rels");
|
||||
if (!oRels.IsValid())
|
||||
return;
|
||||
|
||||
sXml = L"<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">";
|
||||
@ -816,23 +737,18 @@ public:
|
||||
}
|
||||
sXml += L"</Relationships>";
|
||||
|
||||
m_pZipFolder->writeXml(m_sFolder + L"/_rels/.rels", sXml);
|
||||
m_pFolder->writeXml(L"_rels/.rels", sXml);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::wstring sFileFound = sFile.substr(m_sFolder.length());
|
||||
std::wstring::size_type posRemove = sFileFound.find(L"/_xmlsignatures/");
|
||||
std::wstring sFileFound = m_pFolder->getLocalFilePath(sFile);
|
||||
std::wstring::size_type posRemove = sFileFound.find(L"_xmlsignatures/");
|
||||
if (std::wstring::npos != posRemove)
|
||||
sFileFound = sFileFound.substr(posRemove + 16);
|
||||
sFileFound = sFileFound.substr(posRemove + 15);
|
||||
|
||||
std::wstring sOriginRels = m_sFolder + L"/_xmlsignatures/_rels/origin.sigs.rels";
|
||||
|
||||
BYTE* pData = NULL;
|
||||
DWORD dwLen = 0;
|
||||
m_pZipFolder->read(sOriginRels, pData, dwLen);
|
||||
|
||||
XmlUtils::CXmlNode oRels;
|
||||
if (!oRels.FromXmlString(NSFile::CUtf8Converter::GetUnicodeStringFromUTF8(pData, dwLen)))
|
||||
std::wstring sOriginRels = L"_xmlsignatures/_rels/origin.sigs.rels";
|
||||
XmlUtils::CXmlNode oRels = m_pFolder->getNodeFromFile(sOriginRels);
|
||||
if (!oRels.IsValid())
|
||||
return;
|
||||
|
||||
sXml = L"<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">";
|
||||
@ -856,7 +772,7 @@ public:
|
||||
}
|
||||
sXml += L"</Relationships>";
|
||||
|
||||
m_pZipFolder->writeXml(sOriginRels, sXml);
|
||||
m_pFolder->writeXml(sOriginRels, sXml);
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -890,16 +806,20 @@ COOXMLSignature* COOXMLVerifier::GetSignature(const int& index)
|
||||
|
||||
void COOXMLVerifier::RemoveSignature(const std::string& sGuid)
|
||||
{
|
||||
BYTE* pData = NULL;
|
||||
DWORD dwLen = 0;
|
||||
std::wstring sFolder = m_internal->m_sFolder;
|
||||
if (sFolder.empty())
|
||||
m_internal->m_pZipFolder->writeZipFolder(pData, dwLen);
|
||||
|
||||
m_internal->RemoveSignature(sGuid);
|
||||
|
||||
IFolder::CBuffer* buffer = m_internal->m_pFolder->finalize();
|
||||
std::wstring folder = m_internal->m_pFolder->getFullFilePath(L"");
|
||||
RELEASEOBJECT(m_internal);
|
||||
if (sFolder.empty())
|
||||
m_internal = new COOXMLVerifier_private(pData, dwLen);
|
||||
|
||||
if (buffer)
|
||||
{
|
||||
m_internal = new COOXMLVerifier_private(buffer->Buffer, buffer->Size);
|
||||
buffer->UnsetDestroy();
|
||||
delete buffer;
|
||||
}
|
||||
else
|
||||
m_internal = new COOXMLVerifier_private(sFolder);
|
||||
{
|
||||
m_internal = new COOXMLVerifier_private(folder);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
#ifndef _XML_RELS_H_
|
||||
#define _XML_RELS_H_
|
||||
|
||||
#include "../../../xml/include/xmlutils.h"
|
||||
#include "../../../common/StringBuilder.h"
|
||||
#include "../../../common/File.h"
|
||||
#include "../../../common/Directory.h"
|
||||
#include "./ZipFolder.h"
|
||||
|
||||
class COOXMLRelationship
|
||||
{
|
||||
@ -67,11 +67,13 @@ class COOXMLRelationships
|
||||
{
|
||||
public:
|
||||
std::vector<COOXMLRelationship> rels;
|
||||
IFolder* m_pFolder;
|
||||
|
||||
public:
|
||||
|
||||
COOXMLRelationships()
|
||||
{
|
||||
m_pFolder = NULL;
|
||||
}
|
||||
|
||||
COOXMLRelationships(const std::string& xml, std::map<std::wstring, bool>* check_need = NULL)
|
||||
@ -83,18 +85,20 @@ public:
|
||||
FromXmlNode(oNode, check_need);
|
||||
}
|
||||
|
||||
COOXMLRelationships(const std::wstring& xml, const bool& is_file, std::map<std::wstring, bool>* check_need = NULL)
|
||||
COOXMLRelationships(const std::wstring& xml, IFolder* pFolder, std::map<std::wstring, bool>* check_need = NULL)
|
||||
{
|
||||
XmlUtils::CXmlNode oNode;
|
||||
|
||||
if (!is_file)
|
||||
if (NULL == pFolder)
|
||||
{
|
||||
if (!oNode.FromXmlString(xml))
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!oNode.FromXmlFile(xml))
|
||||
m_pFolder = pFolder;
|
||||
oNode = pFolder->getNodeFromFile(xml);
|
||||
if (!oNode.IsValid())
|
||||
return;
|
||||
}
|
||||
|
||||
@ -161,16 +165,16 @@ public:
|
||||
return builder.GetData();
|
||||
}
|
||||
|
||||
void CheckOriginSigs(BYTE*& pData, LONG& nSize)
|
||||
void CheckOriginSigs(const std::wstring& file)
|
||||
{
|
||||
int rId = 0;
|
||||
std::wstring sReplace = L"";
|
||||
std::string sReplace = "";
|
||||
std::vector<COOXMLRelationship>::iterator i = rels.begin();
|
||||
while (i != rels.end())
|
||||
{
|
||||
if (0 == i->target.find(L"_xmlsignatures/"))
|
||||
{
|
||||
sReplace = i->target;
|
||||
sReplace = U_TO_UTF8(i->target);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -187,31 +191,27 @@ public:
|
||||
|
||||
if (!sReplace.empty())
|
||||
{
|
||||
if (sReplace == L"_xmlsignatures/origin.sigs")
|
||||
if (sReplace == "_xmlsignatures/origin.sigs")
|
||||
return;
|
||||
|
||||
std::wstring sXml = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8(pData, nSize);
|
||||
NSStringUtils::string_replace(sXml, sReplace, L"_xmlsignatures/origin.sigs");
|
||||
|
||||
RELEASEARRAYOBJECTS(pData);
|
||||
NSFile::CUtf8Converter::GetUtf8StringFromUnicode(sXml.c_str(), sXml.length(), pData, nSize);
|
||||
std::string sXmlA = m_pFolder->readXml(file);
|
||||
NSStringUtils::string_replaceA(sXmlA, sReplace, "_xmlsignatures/origin.sigs");
|
||||
m_pFolder->writeXmlA(file, sXmlA);
|
||||
return;
|
||||
}
|
||||
|
||||
std::wstring sXml = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8(pData, nSize);
|
||||
std::string sXmlA = m_pFolder->readXml(file);
|
||||
|
||||
std::wstring::size_type pos = sXml.rfind(L"</Relationships>");
|
||||
if (pos == std::wstring::npos)
|
||||
std::string::size_type pos = sXmlA.rfind("</Relationships>");
|
||||
if (pos == std::string::npos)
|
||||
return;
|
||||
|
||||
rId++;
|
||||
std::wstring sRet = sXml.substr(0, pos);
|
||||
sRet += (L"<Relationship Id=\"rId" + std::to_wstring(rId) + L"\" \
|
||||
std::string sRet = sXmlA.substr(0, pos);
|
||||
sRet += ("<Relationship Id=\"rId" + std::to_string(rId) + "\" \
|
||||
Type=\"http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/origin\" Target=\"_xmlsignatures/origin.sigs\"/>\
|
||||
</Relationships>");
|
||||
|
||||
RELEASEARRAYOBJECTS(pData);
|
||||
NSFile::CUtf8Converter::GetUtf8StringFromUnicode(sRet.c_str(), sRet.length(), pData, nSize);
|
||||
m_pFolder->writeXmlA(file, sRet);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
352
DesktopEditor/xmlsec/src/src/ZipFolder.h
Normal file
352
DesktopEditor/xmlsec/src/src/ZipFolder.h
Normal file
@ -0,0 +1,352 @@
|
||||
#ifndef _ZIPFOLDER_H_
|
||||
#define _ZIPFOLDER_H_
|
||||
|
||||
#include "./../../../../OfficeUtils/src/ZipBuffer.h"
|
||||
#include "./../../../common/File.h"
|
||||
#include "./../../../common/Directory.h"
|
||||
#include "../../../xml/include/xmlutils.h"
|
||||
#include "./../include/XmlCertificate.h"
|
||||
|
||||
class IFolder
|
||||
{
|
||||
public:
|
||||
class CBuffer
|
||||
{
|
||||
public:
|
||||
BYTE* Buffer;
|
||||
DWORD Size;
|
||||
|
||||
private:
|
||||
bool m_bIsDestroy;
|
||||
CBuffer(BYTE* data = NULL, DWORD size = 0, bool destroy = false)
|
||||
{
|
||||
Buffer = data;
|
||||
Size = size;
|
||||
m_bIsDestroy = destroy;
|
||||
}
|
||||
public:
|
||||
~CBuffer()
|
||||
{
|
||||
if (m_bIsDestroy && Buffer != NULL)
|
||||
delete [] Buffer;
|
||||
}
|
||||
|
||||
void UnsetDestroy()
|
||||
{
|
||||
m_bIsDestroy = false;
|
||||
}
|
||||
|
||||
friend class IFolder;
|
||||
friend class CFolderSystem;
|
||||
friend class CZipFolderMemory;
|
||||
};
|
||||
|
||||
|
||||
public:
|
||||
// полный путь по локальному
|
||||
virtual std::wstring getFullFilePath(const std::wstring& path) = 0;
|
||||
// локальный путь по полному (без первого '/')
|
||||
virtual std::wstring getLocalFilePath(const std::wstring& path) = 0;
|
||||
// чтение файла в буффер. промежуточный класс нужен, чтобы
|
||||
// одна реализация могли отдавать память напрямую, а другая выделять и не хранить у себя
|
||||
virtual bool read(const std::wstring& path, CBuffer*& buffer) = 0;
|
||||
// запись данных в файл
|
||||
virtual void write(const std::wstring& path, BYTE* data, DWORD length) = 0;
|
||||
// работа с файлами
|
||||
virtual void move(const std::wstring& src, const std::wstring& dst) = 0;
|
||||
virtual bool exists(const std::wstring& path) = 0;
|
||||
virtual void remove(const std::wstring& path) = 0;
|
||||
// работа с директориями
|
||||
virtual void createDirectory(const std::wstring& path) = 0;
|
||||
virtual std::vector<std::wstring> getFiles(const std::wstring& path, bool recursion) = 0;
|
||||
// финализация
|
||||
virtual CBuffer* finalize() { return NULL; }
|
||||
// чтение ноды
|
||||
virtual XmlUtils::CXmlNode getNodeFromFile(const std::wstring& path) = 0;
|
||||
|
||||
// вспомогательные функции
|
||||
void writeXml(const std::wstring& path, const std::wstring& xml)
|
||||
{
|
||||
std::string sXmlUtf8 = U_TO_UTF8(xml);
|
||||
write(path, (BYTE*)sXmlUtf8.c_str(), (DWORD)sXmlUtf8.length());
|
||||
}
|
||||
void writeXmlA(const std::wstring& path, const std::string& xml)
|
||||
{
|
||||
write(path, (BYTE*)xml.c_str(), (DWORD)xml.length());
|
||||
}
|
||||
std::string readXml(const std::wstring& path)
|
||||
{
|
||||
CBuffer* buffer = NULL;
|
||||
if (!read(path, buffer))
|
||||
return "";
|
||||
std::string sXmlUtf8((char*)buffer->Buffer, (size_t)buffer->Size);
|
||||
delete buffer;
|
||||
return sXmlUtf8;
|
||||
}
|
||||
std::string getFileBase64(const std::wstring& path)
|
||||
{
|
||||
CBuffer* buffer = NULL;
|
||||
if (!read(path, buffer))
|
||||
return "";
|
||||
|
||||
char* pData = NULL;
|
||||
int nLen = 0;
|
||||
NSFile::CBase64Converter::Encode(buffer->Buffer, (int)buffer->Size, pData, nLen, NSBase64::B64_BASE64_FLAG_NOCRLF);
|
||||
|
||||
std::string sRet(pData, (size_t)nLen);
|
||||
|
||||
RELEASEARRAYOBJECTS(pData);
|
||||
delete buffer;
|
||||
|
||||
return sRet;
|
||||
}
|
||||
std::string getFileHash(const std::wstring& path, ICertificate* certificate, int nAlg = -1)
|
||||
{
|
||||
CBuffer* buffer = NULL;
|
||||
if (!read(path, buffer))
|
||||
return "";
|
||||
|
||||
std::string sRet = certificate->GetHash(buffer->Buffer, buffer->Size, (nAlg == -1) ? certificate->GetHashAlg() : nAlg);
|
||||
delete buffer;
|
||||
return sRet;
|
||||
}
|
||||
std::wstring getFileHashW(const std::wstring& path, ICertificate* certificate, int nAlg = -1)
|
||||
{
|
||||
std::string sTmp = getFileHash(path, certificate, nAlg);
|
||||
return UTF8_TO_U(sTmp);
|
||||
}
|
||||
};
|
||||
|
||||
class CFolderSystem : public IFolder
|
||||
{
|
||||
std::wstring m_sFolder;
|
||||
|
||||
void correct_folder(std::wstring& folder)
|
||||
{
|
||||
if (!folder.empty() && folder[folder.length() - 1] == '/')
|
||||
folder.erase(folder.length() - 1, 1);
|
||||
}
|
||||
|
||||
public:
|
||||
CFolderSystem(const std::wstring& folder)
|
||||
{
|
||||
m_sFolder = folder;
|
||||
#ifdef _WIN32
|
||||
NSStringUtils::string_replace(m_sFolder, L"\\", L"/");
|
||||
#endif
|
||||
correct_folder(m_sFolder);
|
||||
}
|
||||
|
||||
virtual std::wstring getFullFilePath(const std::wstring& path)
|
||||
{
|
||||
std::wstring full_path = path;
|
||||
#ifdef _WIN32
|
||||
NSStringUtils::string_replace(full_path, L"\\", L"/");
|
||||
#endif
|
||||
if (0 == full_path.find(m_sFolder))
|
||||
return full_path;
|
||||
if (!full_path.empty() && full_path[0] == L'/')
|
||||
return m_sFolder + full_path;
|
||||
return m_sFolder + L"/" + full_path;
|
||||
}
|
||||
virtual std::wstring getLocalFilePath(const std::wstring& path)
|
||||
{
|
||||
std::wstring local_path = path;
|
||||
#ifdef _WIN32
|
||||
NSStringUtils::string_replace(local_path, L"\\", L"/");
|
||||
#endif
|
||||
if (0 == local_path.find(m_sFolder))
|
||||
return local_path.substr(m_sFolder.length() + 1);
|
||||
if (!local_path.empty() && local_path[0] == L'/')
|
||||
return local_path.substr(1);
|
||||
return local_path;
|
||||
}
|
||||
|
||||
virtual bool read(const std::wstring& path, CBuffer*& buffer)
|
||||
{
|
||||
buffer = NULL;
|
||||
std::wstring sPath = getFullFilePath(path);
|
||||
if (NSFile::CFileBinary::Exists(sPath))
|
||||
{
|
||||
BYTE* pData = NULL;
|
||||
DWORD nSize = 0;
|
||||
if (NSFile::CFileBinary::ReadAllBytes(sPath, &pData, nSize))
|
||||
{
|
||||
buffer = new CBuffer(pData, nSize, true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
virtual void write(const std::wstring& path, BYTE* data, DWORD length)
|
||||
{
|
||||
std::wstring sPath = getFullFilePath(path);
|
||||
NSFile::CFileBinary::Remove(sPath);
|
||||
NSFile::CFileBinary oFile;
|
||||
oFile.CreateFileW(sPath);
|
||||
oFile.WriteFile(data, length);
|
||||
oFile.CloseFile();
|
||||
}
|
||||
virtual void move(const std::wstring& sSrc, const std::wstring& sDst)
|
||||
{
|
||||
NSFile::CFileBinary::Move(getFullFilePath(sSrc), getFullFilePath(sDst));
|
||||
}
|
||||
virtual bool exists(const std::wstring& path)
|
||||
{
|
||||
return NSFile::CFileBinary::Exists(getFullFilePath(path));
|
||||
}
|
||||
virtual void remove(const std::wstring& path)
|
||||
{
|
||||
NSFile::CFileBinary::Remove(getFullFilePath(path));
|
||||
}
|
||||
virtual void createDirectory(const std::wstring& path)
|
||||
{
|
||||
std::wstring sPath = getFullFilePath(path);
|
||||
if (!NSDirectory::Exists(sPath))
|
||||
NSDirectory::CreateDirectory(sPath);
|
||||
}
|
||||
virtual std::vector<std::wstring> getFiles(const std::wstring& path, bool bIsRecursion)
|
||||
{
|
||||
std::wstring folder = getFullFilePath(path);
|
||||
correct_folder(folder);
|
||||
std::vector<std::wstring> files = NSDirectory::GetFiles(folder, bIsRecursion);
|
||||
#ifdef _WIN32
|
||||
for (std::vector<std::wstring>::iterator i = files.begin(); i != files.end(); i++)
|
||||
{
|
||||
NSStringUtils::string_replace(*i, L"\\", L"/");
|
||||
}
|
||||
#endif
|
||||
return files;
|
||||
}
|
||||
virtual XmlUtils::CXmlNode getNodeFromFile(const std::wstring& path)
|
||||
{
|
||||
XmlUtils::CXmlNode node;
|
||||
node.FromXmlFile(getFullFilePath(path));
|
||||
return node;
|
||||
}
|
||||
};
|
||||
|
||||
class CZipFolderMemory : public IFolder
|
||||
{
|
||||
CZipBuffer* m_zlib;
|
||||
|
||||
protected:
|
||||
std::string getLocalFilePathA(const std::wstring& path)
|
||||
{
|
||||
if (!path.empty() && path[0] == L'/')
|
||||
return U_TO_UTF8(path.substr(1));
|
||||
return U_TO_UTF8(path);
|
||||
}
|
||||
|
||||
public:
|
||||
CZipFolderMemory(BYTE* data, DWORD length)
|
||||
{
|
||||
m_zlib = new CZipBuffer(data, length);
|
||||
}
|
||||
|
||||
virtual std::wstring getFullFilePath(const std::wstring& path)
|
||||
{
|
||||
return path;
|
||||
}
|
||||
virtual std::wstring getLocalFilePath(const std::wstring& path)
|
||||
{
|
||||
if (!path.empty() && path[0] == L'/')
|
||||
return path.substr(1);
|
||||
return path;
|
||||
}
|
||||
|
||||
virtual bool read(const std::wstring& path, CBuffer*& buffer)
|
||||
{
|
||||
buffer = NULL;
|
||||
std::string sPath = getLocalFilePathA(path);
|
||||
BYTE* pData = NULL;
|
||||
DWORD nSize = 0;
|
||||
m_zlib->getFile(sPath, pData, nSize);
|
||||
if (nSize)
|
||||
{
|
||||
buffer = new CBuffer(pData, nSize, false);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
virtual void write(const std::wstring& path, BYTE* data, DWORD length)
|
||||
{
|
||||
std::string sPath = getLocalFilePathA(path);
|
||||
BYTE* copyData = new BYTE[length];
|
||||
memcpy(copyData, data, length);
|
||||
m_zlib->addFile(sPath, copyData, length);
|
||||
}
|
||||
virtual void move(const std::wstring& sSrc, const std::wstring& sDst)
|
||||
{
|
||||
// TODO: убрать копирование памяти
|
||||
std::string sSrcPath = getLocalFilePathA(sSrc);
|
||||
BYTE* data; DWORD length;
|
||||
m_zlib->getFile(sSrcPath, data, length);
|
||||
BYTE* copyData = new BYTE[length];
|
||||
memcpy(copyData, data, length);
|
||||
m_zlib->removeFile(sSrcPath);
|
||||
m_zlib->addFile(getLocalFilePathA(sDst), copyData, length);
|
||||
}
|
||||
virtual bool exists(const std::wstring& path)
|
||||
{
|
||||
std::string sPath = getLocalFilePathA(path);
|
||||
std::vector<std::string> sPaths = m_zlib->getPaths();
|
||||
return std::find(sPaths.begin(), sPaths.end(), sPath) != sPaths.end();
|
||||
}
|
||||
virtual void remove(const std::wstring& path)
|
||||
{
|
||||
std::string sPath = getLocalFilePathA(path);
|
||||
m_zlib->removeFile(sPath);
|
||||
}
|
||||
virtual void createDirectory(const std::wstring& path)
|
||||
{
|
||||
}
|
||||
virtual std::vector<std::wstring> getFiles(const std::wstring& path, bool bIsRecursion)
|
||||
{
|
||||
std::string sPath = getLocalFilePathA(path);
|
||||
std::vector<std::string> sPaths = m_zlib->getPaths();
|
||||
std::vector<std::wstring> sRes;
|
||||
|
||||
for (std::string& i : sPaths)
|
||||
{
|
||||
if (bIsRecursion)
|
||||
{
|
||||
if (i.find(sPath) == 0)
|
||||
sRes.push_back(L'/' + UTF8_TO_U(i));
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t nFindDirectory = i.find(sPath);
|
||||
if (nFindDirectory == 0)
|
||||
{
|
||||
nFindDirectory = i.find_first_of("\\/", sPath.length());
|
||||
if (nFindDirectory != std::wstring::npos && i.find_first_of("\\/", nFindDirectory + 1) == std::wstring::npos)
|
||||
sRes.push_back(L'/' + UTF8_TO_U(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
return sRes;
|
||||
}
|
||||
virtual CBuffer* finalize()
|
||||
{
|
||||
BYTE* data = NULL;
|
||||
DWORD length = 0;
|
||||
m_zlib->save(data, length);
|
||||
m_zlib->close();
|
||||
return new CBuffer(data, length, true);
|
||||
}
|
||||
virtual XmlUtils::CXmlNode getNodeFromFile(const std::wstring& path)
|
||||
{
|
||||
CBuffer* buffer = NULL;
|
||||
XmlUtils::CXmlNode node;
|
||||
if (!read(path, buffer))
|
||||
return node;
|
||||
|
||||
std::string sUtf8((char*)buffer->Buffer, (size_t)buffer->Size);
|
||||
node.FromXmlStringA(sUtf8);
|
||||
delete buffer;
|
||||
return node;
|
||||
}
|
||||
};
|
||||
|
||||
#endif //_ZIPFOLDER_H_
|
||||
@ -7,6 +7,9 @@
|
||||
//#define USE_MS_CRYPTO
|
||||
#endif
|
||||
|
||||
#define USE_SIGN
|
||||
//#define USE_VERIFY
|
||||
|
||||
int main()
|
||||
{
|
||||
std::wstring sTestDir = NSFile::GetProcessDirectory() + L"/../../";
|
||||
@ -25,6 +28,7 @@ int main()
|
||||
BYTE* pDataDst = NULL;
|
||||
unsigned long nLenDst = 0;
|
||||
|
||||
#ifdef USE_SIGN
|
||||
#if 0
|
||||
COOXMLSigner oSigner(sTestDir + L"file", pCertificate);
|
||||
oSigner.Sign(pDataDst, nLenDst);
|
||||
@ -41,10 +45,23 @@ int main()
|
||||
oFileDst.CreateFileW(sTestDir + L"/file2.docx");
|
||||
oFileDst.WriteFile(pDataDst, nLenDst);
|
||||
oFileDst.CloseFile();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
RELEASEARRAYOBJECTS(pDataDst);
|
||||
|
||||
#ifdef USE_VERIFY
|
||||
#if 1
|
||||
COOXMLVerifier oVerifier(sTestDir + L"file");
|
||||
int nCount = oVerifier.GetSignatureCount();
|
||||
for (int i = 0; i < nCount; i++)
|
||||
{
|
||||
COOXMLSignature* pSign = oVerifier.GetSignature(i);
|
||||
pSign->Check();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
delete pCertificate;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -104,6 +104,7 @@ void CZipBuffer::open(BYTE* buffer, DWORD size)
|
||||
if (file_info.uncompressed_size != 0)
|
||||
m_arrFiles.push_back(CFile(get_filename_from_unzfile(uf), NULL, 0));
|
||||
} while (UNZ_OK == unzGoToNextFile(uf));
|
||||
unzClose(uf);
|
||||
RELEASEOBJECT(buf);
|
||||
}
|
||||
void CZipBuffer::close()
|
||||
@ -111,6 +112,8 @@ void CZipBuffer::close()
|
||||
for (CFile& oFile : m_arrFiles)
|
||||
RELEASEARRAYOBJECTS(oFile.m_pData);
|
||||
m_arrFiles.clear();
|
||||
|
||||
RELEASEARRAYOBJECTS(m_zipFile);
|
||||
}
|
||||
|
||||
std::vector<std::string> CZipBuffer::getPaths()
|
||||
@ -171,7 +174,7 @@ void CZipBuffer::getFile(const std::string& sPath, BYTE*& data, DWORD& length)
|
||||
buf->nSize = m_sizeZip;
|
||||
unzFile uf = unzOpenHelp(buf);
|
||||
|
||||
data = new BYTE;
|
||||
data = NULL;
|
||||
length = 0;
|
||||
get_file_in_archive(uf, sPath.c_str(), &data, length);
|
||||
unzClose(uf);
|
||||
|
||||
Reference in New Issue
Block a user