Commit 234e19d6 authored by ElenaSubbotina's avatar ElenaSubbotina

Merge branch 'develop' of https://github.com/ONLYOFFICE/core into develop

parents 8bcc6d15 62145b72
......@@ -136,13 +136,17 @@ namespace DocFileFormat
}
return btWin32;
}
bool ParseEmbeddedEquation( const std::string & xmlString, std::wstring & newXmlString)
bool VMLPictureMapping::ParseEmbeddedEquation( const std::string & xmlString, std::wstring & newXmlString)
{
newXmlString.clear();
std::wstring sTempXmlFile = NSDirectory::CreateTempFileWithUniqueName(
NSDirectory::GetTempPath(), L"emb");
sTempXmlFile += L".xml";
std::wstring sTempFolder = m_ctx->_doc->m_sTempFolder;
if (sTempFolder.empty())
{
sTempFolder = NSFile::CFileBinary::GetTempPath();
}
std::wstring sTempXmlFile = NSDirectory::CreateTempFileWithUniqueName(sTempFolder, L"emb");
NSFile::CFileBinary file;
file.CreateFileW(sTempXmlFile);
......@@ -186,6 +190,7 @@ namespace DocFileFormat
if (res) break;
}
}
NSFile::CFileBinary::Remove(sTempXmlFile);
return res;
}
//---------------------------------------------------------------
......@@ -299,6 +304,11 @@ namespace DocFileFormat
//встроенная неведомая хуйня
m_isEmbedded = true;
m_embeddedData = std::string((char*)iter->opComplex, iter->op);
//if (ParseEmbeddedBlob( m_embeddedData, m_blobXml)) // todoooo
//{
// m_isEmbedded = false;
//}
}break;
//BORDERS
case borderBottomColor:
......
......@@ -46,7 +46,6 @@ namespace DocFileFormat
{
class OleObject;
bool ParseEmbeddedEquation( const std::string & xmlString, std::wstring & newXmlString );
class VMLPictureMapping: public PropertiesMapping, public IMapping
{
......@@ -58,6 +57,7 @@ namespace DocFileFormat
/// Writes a border element
void writePictureBorder (const std::wstring & name, const BorderCode* brc);
void appendStyleProperty( std::wstring* b, const std::wstring& propName, const std::wstring& propValue ) const;
bool ParseEmbeddedEquation( const std::string & xmlString, std::wstring & newXmlString );
protected:
/// Copies the picture from the binary stream to the zip archive
/// and creates the relationships for the image.
......
......@@ -86,6 +86,7 @@ namespace DocFileFormat
friend class Table;
friend class TableRow;
friend class VMLShapeMapping;
friend class VMLPictureMapping;
friend class OpenXmlPackage;
friend class TextboxMapping;
......
......@@ -336,6 +336,7 @@ void odf_drawing_context::set_background_state(bool Val)
impl_->is_background_ = Val;
impl_->current_graphic_properties = new graphic_format_properties();
start_area_properties();
}
void odf_drawing_context::check_anchor()
......@@ -473,6 +474,7 @@ void odf_drawing_context::start_drawing()
}
void odf_drawing_context::end_drawing_background(odf_types::common_draw_fill_attlist & common_draw_attlist)
{
end_area_properties();
if (impl_->current_drawing_state_.elements_.empty() == false) return;
if (!impl_->is_background_ || !impl_->current_graphic_properties) return;
......@@ -491,15 +493,13 @@ void odf_drawing_context::end_drawing()
draw_base* draw = dynamic_cast<draw_base*>(impl_->current_drawing_state_.elements_[0].elm.get());
if (draw)
{
if (impl_->is_presentation_)
if (impl_->current_drawing_state_.presentation_class_ || impl_->current_drawing_state_.presentation_placeholder_)
{
_CP_OPT(std::wstring) draw_layer;
if (impl_->is_presentation_.get() == true)
{//master
draw_layer = L"backgroundobjects";
//if (impl_->current_drawing_state_.presentation_class_)
// draw_layer = L"backgroundobjects";
//else draw_layer = L"layout";
if (!impl_->current_drawing_state_.presentation_class_)
impl_->current_drawing_state_.presentation_class_ = presentation_class::outline;
......@@ -1186,10 +1186,14 @@ void odf_drawing_context::set_shadow(int type, std::wstring hexColor, _CP_OPT(do
void odf_drawing_context::set_placeholder_id (std::wstring val)
{
if (!impl_->is_presentation_) return;
impl_->current_drawing_state_.presentation_placeholder_ = val;
}
void odf_drawing_context::set_placeholder_type (int val)
{
if (!impl_->is_presentation_) return;
switch(val)
{
case 0: impl_->current_drawing_state_.presentation_class_ = presentation_class::outline; break;
......
......@@ -433,6 +433,8 @@ void OoxConverter::convert(PPTX::Logic::Shape *oox_shape)
{
if (oox_shape == NULL) return;
_CP_OPT(bool) bMasterPresentation = odf_context()->drawing_context()->get_presentation();
odf_context()->drawing_context()->start_drawing();
int type = 1000; //custom
......@@ -448,7 +450,8 @@ void OoxConverter::convert(PPTX::Logic::Shape *oox_shape)
type = preset.GetValue();
}
if (type == SimpleTypes::shapetypeRect && oox_shape->txBody.IsInit()) type = 2000;
if (type == SimpleTypes::shapetypeRect && oox_shape->txBody.IsInit())
type = 2000;
if (type == 2000 && oox_shape->txBody->bodyPr.IsInit()
&& oox_shape->txBody->bodyPr->fromWordArt.get_value_or(false))
......
......@@ -130,6 +130,8 @@ bool OoxConverter::UpdateProgress(long nComplete)
void OoxConverter::set_fonts_directory(const std::wstring &fontsPath)
{
if (odf_context() == NULL) return;
odf_context()->set_fonts_directory(fontsPath);
}
......
......@@ -60,6 +60,17 @@ namespace Oox2Odf
{
PptxConverter::PptxConverter(const std::wstring & path, const ProgressCallback* CallBack)
{
current_clrMap = NULL;
current_slide = NULL;
current_theme = NULL;
current_tableStyles = NULL;
presentation = NULL;
output_document = NULL;
odp_context = NULL;
pCallBack = CallBack;
const OOX::CPath oox_path(std::wstring(path.c_str()));
pptx_document = new PPTX::Folder();
......@@ -82,13 +93,6 @@ PptxConverter::PptxConverter(const std::wstring & path, const ProgressCallback*
output_document = new odf_writer::package::odf_document(L"presentation");
odp_context = new odf_writer::odp_conversion_context(output_document);
current_clrMap = NULL;
current_slide = NULL;
current_theme = NULL;
current_tableStyles = NULL;
pCallBack = CallBack;
if (UpdateProgress(290000))return;
}
PptxConverter::~PptxConverter()
......@@ -339,7 +343,7 @@ void PptxConverter::convert_slides()
current_slide = slide->Master.operator->();
if (bShowLayoutMasterSp && bShowMasterSp)
convert_slide(&slide->Master->cSld, current_txStyles, false);
convert_slide(&slide->Master->cSld, current_txStyles, false, true);
else
convert(slide->Master->cSld.bg.GetPointer());
......@@ -347,7 +351,7 @@ void PptxConverter::convert_slides()
current_clrMap = slide->Layout->clrMapOvr->overrideClrMapping.GetPointer();
current_slide = slide->Layout.operator->();
convert_slide(&slide->Layout->cSld, current_txStyles, true);
convert_slide(&slide->Layout->cSld, current_txStyles, true, bShowLayoutMasterSp);
//add note master
odp_context->end_master_slide();
......@@ -387,7 +391,7 @@ void PptxConverter::convert_slides()
odp_context->current_slide().set_master_page (master_style_name);
odp_context->current_slide().set_layout_page (layout_style_name);
convert_slide (slide->cSld.GetPointer(), current_txStyles);
convert_slide (slide->cSld.GetPointer(), current_txStyles, true, bShowMasterSp);
convert (slide->comments.operator->());
convert (slide->Note.operator->());
......@@ -943,7 +947,7 @@ void PptxConverter::convert(PPTX::Logic::Bg *oox_background)
odp_context->end_drawings();
}
void PptxConverter::convert_slide(PPTX::Logic::CSld *oox_slide, PPTX::Logic::TxStyles* txStyles, bool bPlaceholders)
void PptxConverter::convert_slide(PPTX::Logic::CSld *oox_slide, PPTX::Logic::TxStyles* txStyles, bool bPlaceholders, bool bFillUp)
{
if (oox_slide == NULL) return;
......@@ -966,14 +970,15 @@ void PptxConverter::convert_slide(PPTX::Logic::CSld *oox_slide, PPTX::Logic::TxS
{
if (pShape->nvSpPr.nvPr.ph.is_init())
{
if (bFillUp)
pShape->FillLevelUp();
if (pShape->nvSpPr.nvPr.ph->type.IsInit())
{
int ph_type = pShape->nvSpPr.nvPr.ph->type->GetBYTECode();
if (!bMaster && (ph_type == 5 || ph_type == 6 || ph_type == 7 || ph_type == 12))
continue;
//if (!bMaster && (ph_type == 5 || ph_type == 6 || ph_type == 7 || ph_type == 12))
// continue;
odf_context()->drawing_context()->set_placeholder_type(ph_type);
}
......
......@@ -106,7 +106,7 @@ namespace Oox2Odf
void convert(OOX::WritingElement *oox_unknown);
void convert_slide (PPTX::Logic::CSld *oox_slide, PPTX::Logic::TxStyles* txStyles, bool bPlaceholders = true);
void convert_slide (PPTX::Logic::CSld *oox_slide, PPTX::Logic::TxStyles* txStyles, bool bPlaceholders, bool bFillUp);
void convert_layout (PPTX::Logic::CSld *oox_slide);
void convert (PPTX::Comments *oox_comments);
void convert (PPTX::NotesSlide *oox_note);
......
......@@ -120,21 +120,29 @@ namespace PPTX
oAttr.Write(_T("noResize"), noResize);
oAttr.Write(_T("noSelect"), noSelect);
return XmlUtils::CreateNode(m_namespace + L":cNvGraphicFramePr", oAttr.m_strValue.empty() ? L"" : XmlUtils::CreateNode(L"a:graphicFrameLocks", oAttr));
std::wstring namespaceLocks = L"a";
if (m_namespace == L"wp") namespaceLocks = L"wp";
return XmlUtils::CreateNode(m_namespace + L":cNvGraphicFramePr", oAttr.m_strValue.empty() ? L"" : XmlUtils::CreateNode(namespaceLocks + L":graphicFrameLocks", oAttr));
}
virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const
{
std::wstring namespace_ = m_namespace;
std::wstring namespaceLock_ = L"a";
if (pWriter->m_lDocType == XMLWRITER_DOC_TYPE_XLSX) namespace_ = L"xdr";
if (pWriter->m_lDocType == XMLWRITER_DOC_TYPE_DOCX) namespace_ = L"wp";
if (pWriter->m_lDocType == XMLWRITER_DOC_TYPE_DOCX)
{
namespaceLock_ = L"wp";
namespace_ = L"wp";
}
pWriter->StartNode(namespace_ + L":cNvGraphicFramePr");
pWriter->EndAttributes();
pWriter->StartNode(_T("a:graphicFrameLocks"));
pWriter->StartNode(namespaceLock_ + L"graphicFrameLocks");
pWriter->StartAttributes();
......@@ -147,7 +155,7 @@ namespace PPTX
pWriter->EndAttributes();
pWriter->EndNode(_T("a:graphicFrameLocks"));
pWriter->EndNode(namespaceLock_ + L":graphicFrameLocks");
pWriter->EndNode(namespace_ + L":cNvGraphicFramePr");
}
......
......@@ -122,8 +122,8 @@ namespace PPTX
if (L"xfrm" == strName && strNamespace != L"xdr")
xfrm = oReader;
else if (L"nvGraphicFramePr" == strName)
nvGraphicFramePr.fromXML( oReader );
else if (L"cNvGraphicFramePr" == strName)
nvGraphicFramePr.cNvGraphicFramePr.fromXML( oReader );
else if (L"graphic" == strName)
{
......
......@@ -156,6 +156,16 @@ namespace PPTX
}
}
}
if (pShape->nvSpPr.nvPr.ph->idx.IsInit())
{
//not found in layout !! 100818_건강보험과_보건의료_김용익_최종.pptx
bool bShapeMaster = showMasterSp.get_value_or(true);
if (Master.IsInit() && bShapeMaster)
{
Master->GetLevelUp(pShape);
}
}
}
}
virtual std::wstring GetMediaFullPathNameFromRId(const OOX::RId& rid)const
......
......@@ -45,7 +45,8 @@
#include <windows.h>
#endif
#define U_TO_UTF8(val) NSFile::CUtf8Converter::GetUtf8StringFromUnicode2(val.c_str(), val.length())
#define U_TO_UTF8(val) NSFile::CUtf8Converter::GetUtf8StringFromUnicode2(val.c_str(), (LONG)val.length())
#define UTF8_TO_U(val) NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)val.c_str(), (LONG)val.length())
#if defined(__linux__) || defined(_MAC) && !defined(_IOS)
#include <unistd.h>
......
......@@ -7,71 +7,336 @@
#include <string>
#include "../../../common/File.h"
#include "../../../common/Directory.h"
#include "../../../common/BigInteger.h"
#include "../../../xml/include/xmlutils.h"
#include "../../../xml/libxml2/include/libxml/c14n.h"
#include <vector>
#pragma comment (lib, "crypt32.lib")
#pragma comment (lib, "cryptui.lib")
#pragma comment (lib, "Advapi32.lib")
//#define ENUMS_CERTS
//////////////////////
class CXmlBuffer
class CXmlCanonicalizator
{
public:
private:
class CXmlBuffer
{
public:
NSStringUtils::CStringBuilderA builder;
public:
public:
CXmlBuffer()
{
}
~CXmlBuffer()
{
}
};
};
static int xmlBufferIOWrite(CXmlBuffer* buf, const char* buffer, int len)
{
static int buffer_xmlBufferIOWrite(CXmlBuffer* buf, const char* buffer, int len)
{
buf->builder.WriteString(buffer, (size_t)len);
return len;
}
}
static int xmlBufferIOClose(CXmlBuffer* buf)
{
static int buffer_xmlBufferIOClose(CXmlBuffer* buf)
{
return 0;
}
}
int xmlC14NIsVisibleCallbackMy(void * user_data, xmlNodePtr node, xmlNodePtr parent)
{
static int buffer_xmlC14NIsVisibleCallback(void * user_data, xmlNodePtr node, xmlNodePtr parent)
{
if (node->type == XML_TEXT_NODE)
{
std::string sTmp((char*)node->content);
if (std::string::npos != sTmp.find('\n') ||
std::string::npos != sTmp.find('\r') ||
std::string::npos != sTmp.find('\t'))
const char* cur = (char*)node->content;
size_t size = strlen(cur);
for (size_t i = 0; i < size; ++i, ++cur)
{
return 0;
if (*cur != '\n' && *cur != '\r' && *cur != '\t')
return 1;
}
return 0;
}
return 1;
}
}
//////////////////////
public:
static std::string Execute(const std::string& sXml, int mode)
{
xmlDocPtr xmlDoc = xmlParseMemory((char*)sXml.c_str(), (int)sXml.length());
#define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
void MyHandleError(char *s);
CXmlBuffer bufferC14N;
xmlOutputBufferPtr _buffer = xmlOutputBufferCreateIO((xmlOutputWriteCallback)buffer_xmlBufferIOWrite,
(xmlOutputCloseCallback)buffer_xmlBufferIOClose,
&bufferC14N,
NULL);
bool Sign(PCCERT_CONTEXT pCertContext, std::wstring sFileXml, std::wstring sSignatureFile);
bool Verify(PCCERT_CONTEXT pCertContext, std::wstring sFileXml, std::wstring sSignatureFile);
xmlC14NExecute(xmlDoc, buffer_xmlC14NIsVisibleCallback, NULL, mode, NULL, 0, _buffer);
xmlOutputBufferClose(_buffer);
return bufferC14N.builder.GetData();
}
static std::string Execute(const std::wstring& sXmlFile, int mode)
{
std::string sXml;
NSFile::CFileBinary::ReadAllTextUtf8A(sXmlFile, sXml);
xmlDocPtr xmlDoc = xmlParseMemory((char*)sXml.c_str(), (int)sXml.length());
return Execute(sXml, mode);
}
};
void ConvertEndian(const BYTE* src, BYTE* dst, DWORD size)
class CXmlSigner
{
private:
PCCERT_CONTEXT m_context;
public:
CXmlSigner(PCCERT_CONTEXT pCertContext)
{
m_context = pCertContext;
}
~CXmlSigner()
{
}
public:
std::string Sign(std::string sXml)
{
BOOL bResult = TRUE;
DWORD dwKeySpec = 0;
HCRYPTHASH hHash = NULL;
HCRYPTPROV hCryptProv = NULL;
bResult = CryptAcquireCertificatePrivateKey(m_context, 0, NULL, &hCryptProv, &dwKeySpec, NULL);
if (!bResult)
return "";
bResult = CryptCreateHash(hCryptProv, CALG_SHA1, 0, 0, &hHash);
if (!bResult)
{
CryptReleaseContext(hCryptProv, 0);
return "";
}
bResult = CryptHashData(hHash, (BYTE*)sXml.c_str(), (DWORD)sXml.length(), 0);
if (!bResult)
{
CryptDestroyHash(hHash);
CryptReleaseContext(hCryptProv, 0);
return "";
}
DWORD dwSigLen = 0;
BYTE* pbSignature = NULL;
bResult = CryptSignHash(hHash, dwKeySpec, NULL, 0, NULL, &dwSigLen);
if (!bResult)
{
CryptDestroyHash(hHash);
CryptReleaseContext(hCryptProv, 0);
return "";
}
pbSignature = new BYTE[dwSigLen];
bResult = CryptSignHash(hHash, dwKeySpec, NULL, 0, pbSignature, &dwSigLen);
if (!bResult)
{
CryptDestroyHash(hHash);
CryptReleaseContext(hCryptProv, 0);
return "";
}
BYTE* pbSignatureMem = new BYTE[dwSigLen];
ConvertEndian(pbSignature, pbSignatureMem, dwSigLen);
char* pBase64 = NULL;
int nBase64Len = 0;
NSFile::CBase64Converter::Encode(pbSignatureMem, (int)dwSigLen, pBase64, nBase64Len, NSBase64::B64_BASE64_FLAG_NONE);
delete[] pbSignature;
delete[] pbSignatureMem;
bResult = CryptDestroyHash(hHash);
std::string sReturn(pBase64, nBase64Len);
delete[] pBase64;
CryptReleaseContext(hCryptProv, 0);
return sReturn;
}
std::string GetHash(BYTE* pData, DWORD dwSize)
{
BOOL bResult = TRUE;
DWORD dwKeySpec = 0;
HCRYPTHASH hHash = NULL;
HCRYPTPROV hCryptProv = NULL;
bResult = CryptAcquireCertificatePrivateKey(m_context, 0, NULL, &hCryptProv, &dwKeySpec, NULL);
if (!bResult)
return "";
bResult = CryptCreateHash(hCryptProv, CALG_SHA1, 0, 0, &hHash);
if (!bResult)
{
CryptReleaseContext(hCryptProv, 0);
return "";
}
bResult = CryptHashData(hHash, pData, dwSize, 0);
if (!bResult)
{
CryptDestroyHash(hHash);
CryptReleaseContext(hCryptProv, 0);
return "";
}
DWORD cbHashSize = 0, dwCount = sizeof(DWORD);
bResult = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&cbHashSize, &dwCount, 0);
if (!bResult)
{
CryptDestroyHash(hHash);
CryptReleaseContext(hCryptProv, 0);
return "";
}
BYTE* pDataHashRaw = new BYTE[dwCount];
bResult = CryptGetHashParam(hHash, HP_HASHVAL, pDataHashRaw, &cbHashSize, 0);
if (!bResult)
{
CryptDestroyHash(hHash);
CryptReleaseContext(hCryptProv, 0);
return "";
}
char* pBase64_hash = NULL;
int nBase64Len_hash = 0;
NSFile::CBase64Converter::Encode(pDataHashRaw, (int)cbHashSize, pBase64_hash, nBase64Len_hash, NSBase64::B64_BASE64_FLAG_NOCRLF);
std::string sReturn(pBase64_hash, nBase64Len_hash);
delete [] pBase64_hash;
//delete [] pDataHashRaw;
CryptDestroyHash(hHash);
CryptReleaseContext(hCryptProv, 0);
return sReturn;
}
std::string GetHash(std::string& sXml)
{
return GetHash((BYTE*)sXml.c_str(), (DWORD)sXml.length());
}
std::string GetHash(std::wstring& sXmlFile)
{
BYTE* pFileData = NULL;
DWORD dwFileDataLen = 0;
NSFile::CFileBinary::ReadAllBytes(sXmlFile, &pFileData, dwFileDataLen);
if (0 == dwFileDataLen)
return "";
std::string sReturn = GetHash(pFileData, dwFileDataLen);
RELEASEARRAYOBJECTS(pFileData);
return sReturn;
}
BOOL Verify(std::string& sXml, std::string& sXmlSignature)
{
DWORD dwKeySpec = 0;
HCRYPTHASH hHash = NULL;
HCRYPTKEY hPubKey = NULL;
HCRYPTPROV hCryptProv = NULL;
BOOL bResult = CryptAcquireCertificatePrivateKey(m_context, 0, NULL, &hCryptProv, &dwKeySpec, NULL);
if (!bResult)
return FALSE;
bResult = CryptCreateHash(hCryptProv, CALG_SHA1, 0, 0, &hHash);
if (!bResult)
{
CryptReleaseContext(hCryptProv, 0);
return FALSE;
}
BYTE* pDataHash = NULL;
DWORD dwHashLen = 0;
int nTmp = 0;
NSFile::CBase64Converter::Decode((char*)sXmlSignature.c_str(), (int)sXmlSignature.length(), pDataHash, nTmp);
dwHashLen = (DWORD)nTmp;
BYTE* pDataHashMem = new BYTE[dwHashLen];
ConvertEndian(pDataHash, pDataHashMem, dwHashLen);
RELEASEARRAYOBJECTS(pDataHash);
bResult = CryptHashData(hHash, (BYTE*)sXml.c_str(), (DWORD)sXml.length(), 0);
// Get the public key from the certificate
CryptImportPublicKeyInfo(hCryptProv, m_context->dwCertEncodingType, &m_context->pCertInfo->SubjectPublicKeyInfo, &hPubKey);
BOOL bResultRet = CryptVerifySignature(hHash, pDataHashMem, dwHashLen, hPubKey, NULL, 0);
delete[] pDataHashMem;
bResult = CryptDestroyHash(hHash);
CryptDestroyKey(hPubKey);
CryptReleaseContext(hCryptProv, 0);
return bResultRet && bResult;
}
std::string GetCertificateBase64()
{
char* pData = NULL;
int nDataLen = 0;
NSFile::CBase64Converter::Encode(m_context->pbCertEncoded, (int)m_context->cbCertEncoded, pData, nDataLen, NSBase64::B64_BASE64_FLAG_NOCRLF);
std::string sReturn(pData, nDataLen);
RELEASEARRAYOBJECTS(pData);
return sReturn;
}
std::string GetCertificateHash()
{
return GetHash(m_context->pbCertEncoded, (int)m_context->cbCertEncoded);
}
public:
static void ConvertEndian(const BYTE* src, BYTE* dst, DWORD size)
{
for(BYTE* p = dst + size - 1; p >= dst; ++src, --p)
(*p) = (*src);
}
}
};
#define MY_ENCODING_TYPE (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING)
void MyHandleError(char *s);
bool Sign(PCCERT_CONTEXT pCertContext, std::wstring sFileXml, std::wstring sSignatureFile);
bool Verify(PCCERT_CONTEXT pCertContext, std::wstring sFileXml, std::wstring sSignatureFile);
bool SignDocument(std::wstring sFolderOOXML, PCCERT_CONTEXT pCertContext);
void main(void)
{
......@@ -379,10 +644,19 @@ void main(void)
MyHandleError("Select UI failed." );
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
if (false)
{
bool bRes = true;
bRes = Sign(pCertContext, NSFile::GetProcessDirectory() + L"/test.xml", NSFile::GetProcessDirectory() + L"/result.txt");
bRes = Verify(pCertContext, NSFile::GetProcessDirectory() + L"/test.xml", NSFile::GetProcessDirectory() + L"/result.txt");
CXmlSigner oSigner(pCertContext);
std::string sCertBase64 = oSigner.GetCertificateBase64();
std::string sCertHash = oSigner.GetCertificateHash();
}
SignDocument(NSFile::GetProcessDirectory() + L"/ImageStamp", pCertContext);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CertFreeCertificateContext(pCertContext);
......@@ -401,141 +675,323 @@ void MyHandleError(LPTSTR psz)
bool Sign(PCCERT_CONTEXT pCertContext, std::wstring sFileXml, std::wstring sSignatureFile)
{
// Variables
HCRYPTPROV hCryptProv = NULL;
DWORD dwKeySpec = 0;
HCRYPTHASH hHash = NULL;
std::string sXmlPrepare = CXmlCanonicalizator::Execute(sFileXml, XML_C14N_1_0);
BOOL bResult = FALSE;
CXmlSigner oSigner(pCertContext);
std::string sXmlSigned = oSigner.Sign(sXmlPrepare);
DWORD dwSigLen = 0;
BYTE* pbSignature = NULL;
NSFile::CFileBinary oFile;
oFile.CreateFileW(sSignatureFile);
oFile.WriteFile((BYTE*)sXmlSigned.c_str(), (DWORD)sXmlSigned.length());
oFile.CloseFile();
bResult = CryptAcquireCertificatePrivateKey(pCertContext, 0, NULL, &hCryptProv, &dwKeySpec, NULL);
return (!sXmlSigned.empty());
}
bool bIsResult = ((dwKeySpec & AT_SIGNATURE) == AT_SIGNATURE);
bool Verify(PCCERT_CONTEXT pCertContext, std::wstring sFileXml, std::wstring sSignatureFile)
{
std::string sXmlUtf8;
NSFile::CFileBinary::ReadAllTextUtf8A(sFileXml, sXmlUtf8);
// Create the hash object.
bResult = CryptCreateHash(hCryptProv, CALG_SHA1, 0, 0, &hHash);
std::string sXmlUtf8Prepare = CXmlCanonicalizator::Execute(sXmlUtf8, XML_C14N_1_0);
BYTE* pDataSrc = NULL;
DWORD dwFileSrcLen = 0;
NSFile::CFileBinary::ReadAllBytes(sFileXml, &pDataSrc, dwFileSrcLen);
std::string sXmlUtf8Signature;
NSFile::CFileBinary::ReadAllTextUtf8A(sSignatureFile, sXmlUtf8Signature);
xmlDocPtr xmlDoc = xmlParseMemory((char*)pDataSrc, (int)dwFileSrcLen);
if (sXmlUtf8Prepare.empty() || sXmlUtf8Signature.empty())
return false;
CXmlBuffer _bufferC14N;
xmlOutputBufferPtr _buffer = xmlOutputBufferCreateIO((xmlOutputWriteCallback)xmlBufferIOWrite,
(xmlOutputCloseCallback)xmlBufferIOClose,
&_bufferC14N,
NULL);
CXmlSigner oSigner(pCertContext);
return (TRUE == oSigner.Verify(sXmlUtf8Prepare, sXmlUtf8Signature));
}
xmlC14NExecute(xmlDoc, xmlC14NIsVisibleCallbackMy, NULL, XML_C14N_1_0, NULL, 0, _buffer);
class COOXMLSigner
{
public:
PCCERT_CONTEXT m_context;
std::wstring m_sFolder;
xmlOutputBufferClose(_buffer);
CXmlSigner* m_signer;
NSFile::CFileBinary oFileDump;
oFileDump.CreateFileW(NSFile::GetProcessDirectory() + L"/123.txt");
oFileDump.WriteFile((BYTE*)_bufferC14N.builder.GetBuffer(), (DWORD)_bufferC14N.builder.GetCurSize());
oFileDump.CloseFile();
public:
COOXMLSigner(const std::wstring& sFolder, PCCERT_CONTEXT pContext)
{
m_sFolder = sFolder;
m_context = pContext;
m_signer = new CXmlSigner(pContext);
}
~COOXMLSigner()
{
RELEASEOBJECT(m_signer);
}
//bResult = CryptHashData(hHash, pDataSrc, dwFileSrcLen, 0);
bResult = CryptHashData(hHash, (BYTE*)_bufferC14N.builder.GetBuffer(), (DWORD)_bufferC14N.builder.GetCurSize(), 0);
std::wstring GetReference(const std::wstring& file, const std::wstring& content_type)
{
std::wstring sXml = L"<Reference URI=\"" + file + L"?ContentType=" + content_type + L"\">";
sXml += L"<DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\"/>";
sXml += L"<DigestValue>";
sXml += UTF8_TO_U(m_signer->GetHash(m_sFolder + file));
sXml += L"</DigestValue>";
sXml += L"</Reference>";
return sXml;
}
if (true)
std::string GetHashXml(const std::wstring& xml)
{
DWORD cbHashSize = 0, dwCount = sizeof(DWORD);
std::string sXmlSigned = U_TO_UTF8(xml);
sXmlSigned = CXmlCanonicalizator::Execute(sXmlSigned, XML_C14N_1_0);
return m_signer->GetHash(sXmlSigned);
}
BOOL b1 = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&cbHashSize, &dwCount, 0);
std::string GetReferenceMain(const std::wstring& xml, const std::wstring& id, const bool& isCannon = true)
{
std::wstring sXml1 = L"<Object xmlns=\"http://www.w3.org/2000/09/xmldsig#\"";
if (id.empty())
sXml1 += L">";
else
sXml1 += (L" Id=\"" + id + L"\">");
sXml1 += xml;
sXml1 += L"</Object>";
BYTE* pDataHashRaw = new BYTE[dwCount];
std::string sHash = GetHashXml(sXml1);
BOOL b2 = CryptGetHashParam(hHash, HP_HASHVAL, pDataHashRaw, &cbHashSize, 0);
std::string sRet;
if (isCannon)
sRet = "<Transforms><Transform Algorithm=\"http://www.w3.org/TR/2001/REC-xml-c14n-20010315\"/></Transforms>";
char* pBase64_hash = NULL;
int nBase64Len_hash = 0;
NSFile::CBase64Converter::Encode(pDataHashRaw, (int)cbHashSize, pBase64_hash, nBase64Len_hash, NSBase64::B64_BASE64_FLAG_NONE);
sRet += ("<DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\"/><DigestValue>" + sHash + "</DigestValue>");
delete [] pBase64_hash;
return sRet;
}
// Sign the hash object
dwSigLen = 0;
bResult = CryptSignHash(hHash, dwKeySpec, NULL, 0, NULL, &dwSigLen);
std::wstring GetImageBase64(const std::wstring& file)
{
BYTE* pData = NULL;
DWORD dwLen = 0;
if (!NSFile::CFileBinary::ReadAllBytes(file, &pData, dwLen))
return L"";
pbSignature = new BYTE[dwSigLen];
bResult = CryptSignHash(hHash, dwKeySpec, NULL, 0, pbSignature, &dwSigLen);
char* pDataC = NULL;
int nLen = 0;
NSFile::CBase64Converter::Encode(pData, (int)dwLen, pDataC, nLen, NSBase64::B64_BASE64_FLAG_NOCRLF);
NSFile::CFileBinary oFileTmp;
oFileTmp.CreateFileW(NSFile::GetProcessDirectory() + L"/HASH.bin");
oFileTmp.WriteFile(pbSignature, dwSigLen);
oFileTmp.CloseFile();
std::wstring sReturn = NSFile::CUtf8Converter::GetUnicodeFromCharPtr(pDataC, (LONG)nLen, FALSE);
BYTE* pbSignatureMem = new BYTE[dwSigLen];
ConvertEndian(pbSignature, pbSignatureMem, dwSigLen);
RELEASEARRAYOBJECTS(pData);
RELEASEARRAYOBJECTS(pDataC);
NSFile::CFileBinary oFile;
oFile.CreateFileW(sSignatureFile);
return sReturn;
}
};
//oFile.WriteFile(pbSignature, dwSigLen);
char* pBase64 = NULL;
int nBase64Len = 0;
NSFile::CBase64Converter::Encode(pbSignatureMem, (int)dwSigLen, pBase64, nBase64Len, NSBase64::B64_BASE64_FLAG_NONE);
oFile.WriteFile((BYTE*)pBase64, (DWORD)nBase64Len);
bool SignDocument(std::wstring sFolderOOXML, PCCERT_CONTEXT pCertContext)
{
std::wstring sFolder = NSFile::GetProcessDirectory();
oFile.CloseFile();
COOXMLSigner oOOXMLSigner(sFolderOOXML, pCertContext);
delete[] pbSignature;
delete[] pbSignatureMem;
delete[] pDataSrc;
std::string sSignedData;
std::wstring sXmlData;
bResult = CryptDestroyHash(hHash);
std::wstring sDataSign = L"2017-04-21T08:30:21Z";
return (bResult == TRUE);
}
sSignedData += "<CanonicalizationMethod Algorithm=\"http://www.w3.org/TR/2001/REC-xml-c14n-20010315\"/>\
<SignatureMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#rsa-sha1\"/>";
bool Verify(PCCERT_CONTEXT pCertContext, std::wstring sFileXml, std::wstring sSignatureFile)
{
DWORD dwKeySpec = 0;
HCRYPTPROV hCryptProv = NULL;
HCRYPTHASH hHash = NULL;
HCRYPTKEY hPubKey = NULL;
if (true)
{
// idPackageObject
std::wstring sXml = L"<Manifest>";
BOOL bResult = CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
// TODO: rels
if (true)
{
sXml += L"<Reference URI=\"/_rels/.rels?ContentType=application/vnd.openxmlformats-package.relationships+xml\">\
<Transforms><Transform Algorithm=\"http://schemas.openxmlformats.org/package/2006/RelationshipTransform\">\
<mdssi:RelationshipReference xmlns:mdssi=\"http://schemas.openxmlformats.org/package/2006/digital-signature\" SourceId=\"rId1\"/>\
</Transform><Transform Algorithm=\"http://www.w3.org/TR/2001/REC-xml-c14n-20010315\"/></Transforms>\
<DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\"/>\
<DigestValue>1vWU/YTF/7t6ZjnE44gAFTbZvvA=</DigestValue>\
</Reference>";
// Create the hash object.
bResult = CryptCreateHash(hCryptProv, CALG_SHA1, 0, 0, &hHash);
sXml += L"<Reference URI=\"/word/_rels/document.xml.rels?ContentType=application/vnd.openxmlformats-package.relationships+xml\">\
<Transforms><Transform Algorithm=\"http://schemas.openxmlformats.org/package/2006/RelationshipTransform\">\
<mdssi:RelationshipReference xmlns:mdssi=\"http://schemas.openxmlformats.org/package/2006/digital-signature\" SourceId=\"rId3\"/>\
<mdssi:RelationshipReference xmlns:mdssi=\"http://schemas.openxmlformats.org/package/2006/digital-signature\" SourceId=\"rId2\"/>\
<mdssi:RelationshipReference xmlns:mdssi=\"http://schemas.openxmlformats.org/package/2006/digital-signature\" SourceId=\"rId1\"/>\
<mdssi:RelationshipReference xmlns:mdssi=\"http://schemas.openxmlformats.org/package/2006/digital-signature\" SourceId=\"rId6\"/>\
<mdssi:RelationshipReference xmlns:mdssi=\"http://schemas.openxmlformats.org/package/2006/digital-signature\" SourceId=\"rId5\"/>\
<mdssi:RelationshipReference xmlns:mdssi=\"http://schemas.openxmlformats.org/package/2006/digital-signature\" SourceId=\"rId4\"/>\
</Transform><Transform Algorithm=\"http://www.w3.org/TR/2001/REC-xml-c14n-20010315\"/></Transforms>\
<DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\"/>\
<DigestValue>kVYCpjZZG3SU5+sOsB1PRnQSCzk=</DigestValue>\
</Reference>";
}
BYTE* pDataSrc = NULL;
DWORD dwFileSrcLen = 0;
NSFile::CFileBinary::ReadAllBytes(sFileXml, &pDataSrc, dwFileSrcLen);
BYTE* pDataHashBase64 = NULL;
DWORD dwFileHashSrcLenBase64 = 0;
NSFile::CFileBinary::ReadAllBytes(sSignatureFile, &pDataHashBase64, dwFileHashSrcLenBase64);
sXml += oOOXMLSigner.GetReference(L"/word/document.xml", L"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml");
sXml += oOOXMLSigner.GetReference(L"/word/fontTable.xml", L"application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml");
sXml += oOOXMLSigner.GetReference(L"/word/media/image1.emf", L"image/x-emf");
sXml += oOOXMLSigner.GetReference(L"/word/settings.xml", L"application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml");
sXml += oOOXMLSigner.GetReference(L"/word/styles.xml", L"application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml");
sXml += oOOXMLSigner.GetReference(L"/word/theme/theme1.xml", L"application/vnd.openxmlformats-officedocument.theme+xml");
sXml += oOOXMLSigner.GetReference(L"/word/webSettings.xml", L"application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml");
BYTE* pDataHash = NULL;
DWORD dwHashLen = 0;
int nTmp = 0;
NSFile::CBase64Converter::Decode((char*)pDataHashBase64, (int)dwFileHashSrcLenBase64, pDataHash, nTmp);
dwHashLen = (DWORD)nTmp;
sXml += L"</Manifest>";
BYTE* pDataHashMem = new BYTE[dwHashLen];
ConvertEndian(pDataHash, pDataHashMem, dwHashLen);
sXml += L"<SignatureProperties><SignatureProperty Id=\"idSignatureTime\" Target=\"#idPackageSignature\">";
sXml += (L"<mdssi:SignatureTime xmlns:mdssi=\"http://schemas.openxmlformats.org/package/2006/digital-signature\">\
<mdssi:Format>YYYY-MM-DDThh:mm:ssTZD</mdssi:Format>\
<mdssi:Value>" + sDataSign + L"</mdssi:Value>\
</mdssi:SignatureTime></SignatureProperty></SignatureProperties>");
bResult = CryptHashData(hHash, pDataSrc, dwFileSrcLen, 0);
sXmlData += (L"<Object Id=\"idPackageObject\">" + sXml + L"</Object>");
// Get the public key from the certificate
CryptImportPublicKeyInfo(hCryptProv, PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, &pCertContext->pCertInfo->SubjectPublicKeyInfo, &hPubKey);
sSignedData += ("<Reference Type=\"http://www.w3.org/2000/09/xmldsig#Object\" URI=\"#idPackageObject\">" +
oOOXMLSigner.GetReferenceMain(sXml, L"idPackageObject", false) + "</Reference>");
}
BOOL bResultRet = CryptVerifySignature(hHash, pDataHashMem, dwHashLen, hPubKey, NULL, 0);
delete[] pDataSrc;
delete[] pDataHash;
delete[] pDataHashMem;
delete[] pDataHashBase64;
std::wstring sImageValid = oOOXMLSigner.GetImageBase64(sFolder + L"/../../../resources/valid.png");
std::wstring sImageInValid = oOOXMLSigner.GetImageBase64(sFolder + L"/../../../resources/invalid.png");
bResult = CryptDestroyHash(hHash);
if (true)
{
// idOfficeObject
std::wstring sXml = L"<SignatureProperties>\
<SignatureProperty Id=\"idOfficeV1Details\" Target=\"#idPackageSignature\">\
<SignatureInfoV1 xmlns=\"http://schemas.microsoft.com/office/2006/digsig\">\
<SetupID>{39B6B9C7-60AD-45A2-9F61-40C74A24042E}</SetupID>\
<SignatureText></SignatureText>\
<SignatureImage>" + sImageValid + L"</SignatureImage>\
<SignatureComments/>\
<WindowsVersion>10.0</WindowsVersion>\
<OfficeVersion>16.0</OfficeVersion>\
<ApplicationVersion>16.0</ApplicationVersion>\
<Monitors>2</Monitors>\
<HorizontalResolution>1680</HorizontalResolution>\
<VerticalResolution>1050</VerticalResolution>\
<ColorDepth>32</ColorDepth>\
<SignatureProviderId>{00000000-0000-0000-0000-000000000000}</SignatureProviderId>\
<SignatureProviderUrl/>\
<SignatureProviderDetails>9</SignatureProviderDetails>\
<SignatureType>2</SignatureType>\
</SignatureInfoV1>\
</SignatureProperty>\
</SignatureProperties>";
sXmlData += (L"<Object Id=\"idOfficeObject\">" + sXml + L"</Object>");
sSignedData += ("<Reference Type=\"http://www.w3.org/2000/09/xmldsig#Object\" URI=\"#idOfficeObject\">" +
oOOXMLSigner.GetReferenceMain(sXml, L"idOfficeObject", false) + "</Reference>");
}
return bResultRet && bResult;
if (true)
{
DWORD dwNameLen = CertGetNameStringW(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, CERT_NAME_ISSUER_FLAG, NULL, NULL, 0);
wchar_t* pNameData = new wchar_t[dwNameLen];
CertGetNameStringW(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, CERT_NAME_ISSUER_FLAG, NULL, pNameData, dwNameLen);
std::wstring sName(pNameData);
RELEASEARRAYOBJECTS(pNameData);
int nNumberLen = (int)pCertContext->pCertInfo->SerialNumber.cbData;
BYTE* pNumberData = new BYTE[nNumberLen];
CXmlSigner::ConvertEndian(pCertContext->pCertInfo->SerialNumber.pbData, pNumberData, (DWORD)nNumberLen);
CBigInteger oInteger(pNumberData, nNumberLen);
delete[] pNumberData;
std::string sKeyA = oInteger.ToString();
std::wstring sKey = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)sKeyA.c_str(), (LONG)sKeyA.length());
std::wstring sXml = (L"<xd:SignedSignatureProperties>\
<xd:SigningTime>" + sDataSign + L"</xd:SigningTime>\
<xd:SigningCertificate>\
<xd:Cert>\
<xd:CertDigest>\
<DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\"/>\
<DigestValue>MJJT2Y0iMxaPGVXBmOLb9bY60pA=</DigestValue>\
</xd:CertDigest>\
<xd:IssuerSerial>\
<X509IssuerName>CN=" + sName + L"</X509IssuerName>\
<X509SerialNumber>" + sKey + L"</X509SerialNumber>\
</xd:IssuerSerial>\
</xd:Cert>\
</xd:SigningCertificate>\
<xd:SignaturePolicyIdentifier>\
<xd:SignaturePolicyImplied/>\
</xd:SignaturePolicyIdentifier>\
</xd:SignedSignatureProperties>");
std::wstring sSignedXml = L"<xd:SignedProperties xmlns=\"http://www.w3.org/2000/09/xmldsig#\" xmlns:xd=\"http://uri.etsi.org/01903/v1.3.2#\" Id=\"idSignedProperties\">";
sSignedXml += sXml;
sSignedXml += L"</xd:SignedProperties>";
sXmlData += L"<Object><xd:QualifyingProperties xmlns:xd=\"http://uri.etsi.org/01903/v1.3.2#\" Target=\"#idPackageSignature\">\
<xd:SignedProperties Id=\"idSignedProperties\">";
sXmlData += sXml;
sXmlData += L"</xd:SignedProperties></xd:QualifyingProperties></Object>";
sSignedData += "<Reference Type=\"http://uri.etsi.org/01903#SignedProperties\" URI=\"#idSignedProperties\">\
<Transforms><Transform Algorithm=\"http://www.w3.org/TR/2001/REC-xml-c14n-20010315\"/></Transforms>\
<DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\"/><DigestValue>";
std::string sXmlTmp = CXmlCanonicalizator::Execute(U_TO_UTF8(sSignedXml), XML_C14N_1_0);
sSignedData += oOOXMLSigner.m_signer->GetHash(sXmlTmp);
sSignedData += "</DigestValue></Reference>";
}
if (true)
{
std::wstring sXml = sImageValid;
sXmlData += (L"<Object Id=\"idValidSigLnImg\">" + sXml + L"</Object>");
sSignedData += ("<Reference Type=\"http://www.w3.org/2000/09/xmldsig#Object\" URI=\"#idValidSigLnImg\">" +
oOOXMLSigner.GetReferenceMain(sXml, L"idValidSigLnImg", false) + "</Reference>");
}
if (true)
{
std::wstring sXml = sImageInValid;
sXmlData += (L"<Object Id=\"idInvalidSigLnImg\">" + sXml + L"</Object>");
sSignedData += ("<Reference Type=\"http://www.w3.org/2000/09/xmldsig#Object\" URI=\"#idInvalidSigLnImg\">" +
oOOXMLSigner.GetReferenceMain(sXml, L"idInvalidSigLnImg", false) + "</Reference>");
}
std::string sXmlPrepend = ("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Signature xmlns=\"http://www.w3.org/2000/09/xmldsig#\" Id=\"idPackageSignature\"><SignedInfo>");
sXmlPrepend += sSignedData;
sXmlPrepend += "</SignedInfo>";
sXmlPrepend += "<SignatureValue>";
std::string sSignedInfo = "<SignedInfo xmlns=\"http://www.w3.org/2000/09/xmldsig#\">" + sSignedData + "</SignedInfo>";
sSignedInfo = CXmlCanonicalizator::Execute(sSignedInfo, XML_C14N_1_0);
sXmlPrepend += oOOXMLSigner.m_signer->Sign(sSignedInfo);
sXmlPrepend += "</SignatureValue>";
sXmlPrepend += ("<KeyInfo><X509Data><X509Certificate>" + oOOXMLSigner.m_signer->GetCertificateBase64() + "</X509Certificate></X509Data></KeyInfo>");
sXmlData = (UTF8_TO_U(sXmlPrepend) + sXmlData);
sXmlData += L"</Signature>";
std::wstring sDirectory = sFolderOOXML + L"/_xmlsignatures";
NSDirectory::CreateDirectory(sDirectory);
NSFile::CFileBinary oFile;
oFile.CreateFileW(sDirectory + L"/origin.sigs");
oFile.CloseFile();
NSFile::CFileBinary::SaveToFile(sDirectory + L"/sig1.xml", sXmlData, false);
NSDirectory::CreateDirectory(sDirectory + L"/_rels");
std::wstring sRels = L"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\
<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\
<Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/package/2006/relationships/digital-signature/signature\" Target=\"sig1.xml\"/>\
</Relationships>";
NSFile::CFileBinary::SaveToFile(sDirectory + L"/_rels/origin.sigs.rels", sRels, false);
return true;
}
......@@ -75,23 +75,23 @@ namespace codegen
}
public void merge(GenMemberPivot val)
{
if (!string.IsNullOrEmpty(val.sName))
if (string.IsNullOrEmpty(this.sName))
sName = val.sName;
if (!string.IsNullOrEmpty(val.sNamespace))
if (string.IsNullOrEmpty(this.sNamespace))
sNamespace = val.sNamespace;
if (!string.IsNullOrEmpty(val.sType))
if (string.IsNullOrEmpty(this.sType))
sType = val.sType;
if (null != val.oSystemType)
if (null == this.oSystemType)
oSystemType = val.oSystemType;
if (val.bIsAttribute.HasValue)
if (!this.bIsAttribute.HasValue)
bIsAttribute = val.bIsAttribute;
if (!string.IsNullOrEmpty(val.sDefAttribute))
if (string.IsNullOrEmpty(this.sDefAttribute))
sDefAttribute = val.sDefAttribute;
if (val.bQualified.HasValue)
if (!this.bQualified.HasValue)
bQualified = val.bQualified;
if (val.nArrayRank.HasValue)
if (!this.nArrayRank.HasValue)
nArrayRank = val.nArrayRank;
if (val.bIsArrayTypesHidden.HasValue)
if (!this.bIsArrayTypesHidden.HasValue)
bIsArrayTypesHidden = val.bIsArrayTypesHidden;
}
public void completeDefaults()
......@@ -105,7 +105,7 @@ namespace codegen
//[System.Xml.Serialization.XmlElementAttribute("c")]
//public CT_CalcCell[] c {
//bIsArray=true;aArrayTypes=[CT_CalcCell]
//nArrayRank=0;aArrayTypes=[CT_CalcCell];bIsArrayTypesHidden=true
//[System.Xml.Serialization.XmlElementAttribute("b", typeof(CT_Boolean))]
//[System.Xml.Serialization.XmlElementAttribute("d", typeof(CT_DateTime))]
......@@ -114,9 +114,18 @@ namespace codegen
//[System.Xml.Serialization.XmlElementAttribute("n", typeof(CT_Number))]
//[System.Xml.Serialization.XmlElementAttribute("s", typeof(CT_String))]
//public object[] Items {
//nArrayRank=0;aArrayTypes=[CT_Boolean, CT_DateTime, CT_Error, CT_Missing, CT_Number, CT_String];bIsArrayTypesHidden=true
//[System.Xml.Serialization.XmlElementAttribute("consolidation", typeof(CT_Consolidation))]
//[System.Xml.Serialization.XmlElementAttribute("extLst", typeof(CT_ExtensionList))]
//[System.Xml.Serialization.XmlElementAttribute("worksheetSource", typeof(CT_WorksheetSource))]
//public object Item
//{
//nArrayRank=null;aArrayTypes=[CT_Consolidation, CT_ExtensionList, CT_WorksheetSource];bIsArrayTypesHidden=true
//[System.Xml.Serialization.XmlArrayItemAttribute("author", IsNullable=false)]
//public string[] authors {
//nArrayRank=0;aArrayTypes=[string];bIsArrayTypesHidden=false
//[System.Xml.Serialization.XmlArrayItemAttribute("b", typeof(CT_Boolean), IsNullable=false)]
//[System.Xml.Serialization.XmlArrayItemAttribute("d", typeof(CT_DateTime), IsNullable=false)]
......@@ -126,12 +135,7 @@ namespace codegen
//[System.Xml.Serialization.XmlArrayItemAttribute("s", typeof(CT_String), IsNullable=false)]
//[System.Xml.Serialization.XmlArrayItemAttribute("x", typeof(CT_Index), IsNullable=false)]
//public object[][] r {
//[System.Xml.Serialization.XmlElementAttribute("consolidation", typeof(CT_Consolidation))]
//[System.Xml.Serialization.XmlElementAttribute("extLst", typeof(CT_ExtensionList))]
//[System.Xml.Serialization.XmlElementAttribute("worksheetSource", typeof(CT_WorksheetSource))]
//public object Item
//{
//nArrayRank=1;aArrayTypes=[CT_Boolean, CT_DateTime, CT_Error, CT_Missing, CT_Number, CT_String, CT_Index];bIsArrayTypesHidden=false
public class GenClassPivot
{
......@@ -222,6 +226,9 @@ namespace codegen
Queue<GenClassPivot> aTemp = new Queue<GenClassPivot>();
List<GenClassPivot> aRes = new List<GenClassPivot>();
string[] aTargetTypes = new string[] { "CT_PivotCacheDefinition", "CT_PivotCacheRecords", "CT_pivotTableDefinition" };
//string[] aTargetTypes = new string[] { "CT_Workbook" };
//string[] aTargetTypes = new string[] { "CT_Comments" };
Dictionary<string, bool> mapTargetSubTypes = new Dictionary<string, bool>();
Dictionary<string, bool> namspaces = new Dictionary<string, bool>();
......@@ -419,16 +426,19 @@ namespace codegen
{
if (1 == aTempMemebers.Count)
{
oGenMember.merge(aTempMemebers[0]);
GenMemberPivot TempMember = aTempMemebers[0];
TempMember.merge(oGenMember);
TempMember.nArrayRank = null;
}
else
{
oGenMember.aArrayTypes = aTempMemebers;
if (bXmlElementAttribute)
oGenMember.bIsArrayTypesHidden = true;
else
oGenMember.bIsArrayTypesHidden = false;
}
else
{
oGenMember.nArrayRank = null;
}
oGenMember.completeDefaults();
return oGenMember;
......
......@@ -59,10 +59,10 @@ namespace codegen
m_mapProcessedClasses[oGenClass.sName] = oGenClass;
}
string sFileJs = "PivotTables.js";
//string sFileJs = "Workbook.js";
oJsSer.AppendFormat("\"use strict\";\r\n");
oJsSer.AppendFormat(Utils.gc_sFilePrefix);
oJsSer.AppendFormat("function getBoolFromXml(val){{return \"0\"!==val && \"false\"!==val && \"off\"!==val;}}\r\n");
oJsSer.AppendFormat("function getXmlFromBool(val){{return val ? \"1\" : \"0\";}}\r\n");
//enums
ProcessEnums(oJsSer, aEnums);
......@@ -163,11 +163,11 @@ namespace codegen
{
if (oGenClass.isRoot())
{
sb.AppendFormat("{0}.prototype.toXml = function() {{\r\n", oGenClass.sName);
sb.AppendFormat("{0}.prototype.toXml = function(writer) {{\r\n", oGenClass.sName);
}
else
{
sb.AppendFormat("{0}.prototype.toXml = function(name) {{\r\n", oGenClass.sName);
sb.AppendFormat("{0}.prototype.toXml = function(writer, name) {{\r\n", oGenClass.sName);
}
sb.AppendFormat("var res = \"\";\r\n");
ProcessToXml(sb, oGenClass);
......@@ -190,7 +190,23 @@ namespace codegen
{
bNeedDoubleArray = true;
}
if (null == oGenMember.aArrayTypes)
if (null != oGenMember.aArrayTypes)
{
for (int j = 0; j < oGenMember.aArrayTypes.Count; ++j)
{
InfoFromMemberElem(oGenMember.aArrayTypes[j], ref bNeedTextNode);
}
}
else
{
InfoFromMemberElem(oGenMember, ref bNeedTextNode);
}
aMembers.Add(oGenMember);
}
}
}
public void InfoFromMemberElem(GenMemberPivot oGenMember, ref bool bNeedTextNode)
{
if (null != oGenMember.oSystemType)
{
......@@ -208,10 +224,6 @@ namespace codegen
}
}
}
aMembers.Add(oGenMember);
}
}
}
void ProcessProperty(StringBuilder sb, List<GenMemberPivot> aAttributes, List<GenMemberPivot> aMembers, bool bNeedTextNode, bool bNeedDoubleArray)
{
if (aAttributes.Count > 0)
......@@ -237,7 +249,12 @@ namespace codegen
{
GenMemberPivot oGenMember = aMembers[i];
if (oGenMember.nArrayRank.HasValue)
{
if (false != oGenMember.bIsArrayTypesHidden)
sb.AppendFormat("this.{0} = [];\r\n", oGenMember.sName);
else
sb.AppendFormat("this.{0} = null;\r\n", oGenMember.sName);
}
else
{
if (null != oGenMember.aArrayTypes)
......@@ -310,8 +327,9 @@ namespace codegen
}
else
{
sb.AppendFormat("//todo check\r\n", getNameWithPrefix(oGenClass, oGenMember), sCodeName);
sb.AppendFormat("//todo check name duplication\r\n", getNameWithPrefix(oGenClass, oGenMember), sCodeName);
}
sb.AppendFormat("this.{0} = [];\r\n", oGenMember.sName);
sb.AppendFormat("}}\r\n", getNameWithPrefix(oGenClass, oGenMember), sCodeName);
nCounter++;
}
......@@ -383,30 +401,26 @@ namespace codegen
for (int i = 0; i < aMembers.Count; ++i)
{
GenMemberPivot oGenMember = aMembers[i];
nCounter = ProcessOnTextNodeFromXmlMember(sb, oGenClass, oGenMember, null, nCounter);
}
}
int ProcessOnTextNodeFromXmlMember(StringBuilder sb, GenClassPivot oGenClass, GenMemberPivot oGenMember, GenMemberPivot oGenMemberContainer, int nCounter)
{
if (0 != nCounter)
sb.AppendFormat("else ");
sb.AppendFormat("if(\"{0}\" === this._curElem){{\r\n", getNameWithPrefix(oGenClass, oGenMember));
if (null != oGenMember.oSystemType)
{
if (oGenMember.nArrayRank.HasValue)
if (null != oGenMember.aArrayTypes)
{
if (oGenMember.nArrayRank > 0)
for (int j = 0; j < oGenMember.aArrayTypes.Count; ++j)
{
sb.AppendFormat("this._curArray.push({0});\r\n", ProcessJsTypeFromXml(oGenMember.oSystemType, "text"));
nCounter = ProcessOnTextNodeFromXmlMember(sb, oGenClass, oGenMember.aArrayTypes[j], nCounter);
}
}
else
{
sb.AppendFormat("this.{0}.push({1});\r\n", oGenMember.sName, ProcessJsTypeFromXml(oGenMember.oSystemType, "text"));
nCounter = ProcessOnTextNodeFromXmlMember(sb, oGenClass, oGenMember, nCounter);
}
}
else
sb.AppendFormat("this.{0} = {1};\r\n", oGenMember.sName, ProcessJsTypeFromXml(oGenMember.oSystemType, "text"));
}
int ProcessOnTextNodeFromXmlMember(StringBuilder sb, GenClassPivot oGenClass, GenMemberPivot oGenMember, int nCounter)
{
if (null != oGenMember.oSystemType)
{
ProcessOnTextNodeFromXmlMemberPrefix(sb, oGenClass, oGenMember, nCounter);
ProcessOnTextNodeFromXmlMemberElem(sb, oGenMember, ProcessJsTypeFromXml(oGenMember.oSystemType, "text"));
nCounter = ProcessOnTextNodeFromXmlMemberPostfix(sb, nCounter);
}
else if (null != oGenMember.sType)
{
......@@ -415,28 +429,45 @@ namespace codegen
{
if (oTemp.bIsEnum)
{
ProcessOnTextNodeFromXmlMemberPrefix(sb, oGenClass, oGenMember, nCounter);
sb.AppendFormat("var val = {0}(text);\r\n", gc_sEnumFromXmlPrefix + oTemp.sName);
sb.AppendFormat("if(-1 !== val){{\r\n");
ProcessOnTextNodeFromXmlMemberElem(sb, oGenMember, "val");
sb.AppendFormat("}}\r\n");
nCounter = ProcessOnTextNodeFromXmlMemberPostfix(sb, nCounter);
}
}
}
return nCounter;
}
void ProcessOnTextNodeFromXmlMemberPrefix(StringBuilder sb, GenClassPivot oGenClass, GenMemberPivot oGenMember, int nCounter)
{
if (0 != nCounter)
sb.AppendFormat("else ");
sb.AppendFormat("if(\"{0}\" === this._curElem){{\r\n", getNameWithPrefix(oGenClass, oGenMember));
}
int ProcessOnTextNodeFromXmlMemberPostfix(StringBuilder sb, int nCounter)
{
sb.AppendFormat("}}\r\n");
nCounter++;
return nCounter;
}
void ProcessOnTextNodeFromXmlMemberElem(StringBuilder sb, GenMemberPivot oGenMember, string sCodeName)
{
if (oGenMember.nArrayRank.HasValue)
{
if (oGenMember.nArrayRank > 0)
{
sb.AppendFormat("this._curArray.push(val);\r\n");
sb.AppendFormat("this._curArray.push({0});\r\n", sCodeName);
}
else
{
sb.AppendFormat("this.{0}.push(val);\r\n", oGenMember.sName);
sb.AppendFormat("this.{0}.push({1});\r\n", oGenMember.sName, sCodeName);
}
}
else
sb.AppendFormat("this.{0} = val;\r\n", oGenMember.sName);
sb.AppendFormat("}}\r\n");
}
}
}
sb.AppendFormat("}}\r\n");
nCounter++;
return nCounter;
sb.AppendFormat("this.{0} = {1};\r\n", oGenMember.sName, sCodeName);
}
void ProcessOnEndNodeFromXml(StringBuilder sb, GenClassPivot oGenClass, List<GenMemberPivot> aMembers)
{
......@@ -527,15 +558,19 @@ namespace codegen
bool bNeedDoubleArray = false;
InfoFromMember(oGenClass, ref aAttributes, ref aMembers, ref bNeedTextNode, ref bNeedDoubleArray);
string sCodeName;
if (oGenClass.isRoot())
{
sb.AppendFormat("res += \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\" standalone=\\\"yes\\\"?>\";\r\n");
sb.AppendFormat("res += \"<{0}{1}\";\r\n", oGenClass.sRootName, gc_sNamespaceToXml);
sCodeName = "\"" + oGenClass.sRootName + "\"";
sb.AppendFormat("writer.WriteXmlString(\"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\" standalone=\\\"yes\\\"?>\");\r\n");
sb.AppendFormat("writer.WriteXmlNodeStart({0});\r\n", sCodeName);
sb.AppendFormat("writer.WriteXmlString(\"{0}\");\r\n", gc_sNamespaceToXml);
}
else
{
sb.AppendFormat("res += \"<\";\r\n");
sb.AppendFormat("res += name;\r\n");
sCodeName = "name";
sb.AppendFormat("writer.WriteXmlNodeStart({0});\r\n", sCodeName);
}
for (int i = 0; i < aAttributes.Count; ++i)
......@@ -546,16 +581,22 @@ namespace codegen
if (aMembers.Count > 0)
{
sb.AppendFormat("res += \">\";\r\n");
sb.AppendFormat("writer.WriteXmlNodeEnd({0}, true);\r\n", sCodeName);
for (int i = 0; i < aMembers.Count; ++i)
{
GenMemberPivot oGenMember = aMembers[i];
bool bNullCheck = true;
string sCodeElem;
if (oGenMember.nArrayRank > 0)
{
if (false == oGenMember.bIsArrayTypesHidden)
{
sb.AppendFormat("if(null !== {0}){{\r\n", oGenMember.sName);
}
sb.AppendFormat("for(var i = 0; i < this.{0}.length; ++i){{\r\n", oGenMember.sName);
sb.AppendFormat("var elem = this.{0}[i];\r\n", oGenMember.sName);
sCodeElem = "elem";
bNullCheck = false;
}
else
{
......@@ -565,21 +606,42 @@ namespace codegen
{
if (false == oGenMember.bIsArrayTypesHidden)
{
sb.AppendFormat("res += \"<{0}>\";\r\n", getNameWithPrefix(oGenClass, oGenMember));
if (bNullCheck)
sb.AppendFormat("if(null !== {0}){{\r\n", sCodeElem);
sb.AppendFormat("writer.WriteXmlNodeEnd(\"{0}\", true);\r\n", getNameWithPrefix(oGenClass, oGenMember));
}
if (oGenMember.nArrayRank.HasValue)
{
string sCodeSubElem;
if (oGenMember.nArrayRank > 0)
{
sb.AppendFormat("for(var j = 0; j < {0}.length; ++j){{\r\n", sCodeElem);
sb.AppendFormat("var subelem = {0}[j];\r\n", sCodeElem);
sCodeSubElem = "subelem";
}
else
{
sb.AppendFormat("for(var i = 0; i < {0}.length; ++i){{\r\n", sCodeElem);
sb.AppendFormat("var elem = {0}[i];\r\n", sCodeElem);
sCodeSubElem = "elem";
}
if (1 == oGenMember.aArrayTypes.Count)
{
GenMemberPivot oTempMember = oGenMember.aArrayTypes[0];
ProcessMemberToXml(sb, oGenClass, oTempMember, sCodeSubElem, false);
}
else
{
for (int j = 0; j < oGenMember.aArrayTypes.Count; ++j)
{
GenMemberPivot oTempMember = oGenMember.aArrayTypes[j];
if (0 != j)
sb.AppendFormat("else ");
sb.AppendFormat("if(subelem instanceof {0}){{\r\n", oTempMember.sType);
sb.AppendFormat("res += subelem.toXml(\"{0}\");\r\n", getNameWithPrefix(oGenClass, oTempMember));
sb.AppendFormat("if({0} instanceof {1}){{\r\n", sCodeSubElem, oTempMember.sType);
sb.AppendFormat("{0}.toXml(writer, \"{1}\");\r\n", sCodeSubElem, getNameWithPrefix(oGenClass, oTempMember));
sb.AppendFormat("}}\r\n");
}
}
sb.AppendFormat("}}\r\n");
}
else
......@@ -593,42 +655,29 @@ namespace codegen
}
if (false == oGenMember.bIsArrayTypesHidden)
{
sb.AppendFormat("res += \"</{0}>\";\r\n", getNameWithPrefix(oGenClass, oGenMember));
}
}
else
{
if (oGenMember.nArrayRank.HasValue)
{
sb.AppendFormat("for(var i = 0; i < {0}.length; ++i){{\r\n", sCodeElem);
sb.AppendFormat("var elem = {0}[i];\r\n", sCodeElem);
ProcessMemberToXml(sb, oGenClass, oGenMember, "elem", false);
sb.AppendFormat("writer.WriteXmlNodeEnd(\"{0}\");\r\n", getNameWithPrefix(oGenClass, oGenMember));
if (bNullCheck)
sb.AppendFormat("}}\r\n");
}
}
else
{
ProcessMemberToXml(sb, oGenClass, oGenMember, sCodeElem, true);
}
}
if (oGenMember.nArrayRank > 0)
{
sb.AppendFormat("}}\r\n");
}
}
if (oGenClass.isRoot())
if (false == oGenMember.bIsArrayTypesHidden)
{
sb.AppendFormat("res += \"</{0}>\";\r\n", oGenClass.sRootName);
sb.AppendFormat("}}\r\n", oGenMember.sName);
}
}
else
{
sb.AppendFormat("res += \"</\";\r\n");
sb.AppendFormat("res += name;\r\n");
sb.AppendFormat("res += \">\";\r\n");
}
sb.AppendFormat("writer.WriteXmlNodeEnd({0});\r\n", sCodeName);
}
else
sb.AppendFormat("res += \"/>\";\r\n");
sb.AppendFormat("writer.WriteXmlNodeEnd({0}, true, true);\r\n", sCodeName);
}
void ProcessMemberToXml(StringBuilder sb, GenClassPivot oGenClass, GenMemberPivot oGenMember, string sElemName, bool checkNull)
{
......@@ -642,15 +691,7 @@ namespace codegen
if (null != oGenMember.oSystemType)
{
if (bIsAttribute)
sb.AppendFormat("res += \" {0}=\\\"\";\r\n", sElemXmlName);
else
sb.AppendFormat("res += \"<{0}>\";\r\n", sElemXmlName);
sb.AppendFormat("res += {0};\r\n", ProcessJsTypeToXml(oGenMember.oSystemType, sElemName));
if (bIsAttribute)
sb.AppendFormat("res += \"\\\"\";\r\n");
else
sb.AppendFormat("res += \"</{0}>\";\r\n", sElemXmlName);
ProcessJsTypeToXml(sb, sElemXmlName, oGenMember.oSystemType, sElemName, bIsAttribute);
}
else if (null != oGenMember.sType)
{
......@@ -660,20 +701,13 @@ namespace codegen
{
if (oGenClassMember.bIsEnum)
{
if (bIsAttribute)
sb.AppendFormat("res += \" {0}=\\\"\";\r\n", sElemXmlName);
else
sb.AppendFormat("res += \"<{0}>\";\r\n", sElemXmlName);
sb.AppendFormat("res += {0}{1}({2});\r\n", gc_sEnumToXmlPrefix, oGenClassMember.sName, sElemName);
if (bIsAttribute)
sb.AppendFormat("res += \"\\\"\";\r\n");
else
sb.AppendFormat("res += \"</{0}>\";\r\n", sElemXmlName);
string sElemNameEnum = gc_sEnumToXmlPrefix + oGenClassMember.sName + "("+ sElemName + ")";
ProcessJsTypeToXml(sb, sElemXmlName, oGenMember.oSystemType, sElemNameEnum, bIsAttribute);
}
else
{
if (!bIsAttribute)
sb.AppendFormat("res += {0}.toXml(\"{1}\");\r\n", sElemName, sElemXmlName);
sb.AppendFormat("res += {0}.toXml(writer, \"{1}\");\r\n", sElemName, sElemXmlName);
}
}
}
......@@ -682,13 +716,21 @@ namespace codegen
sb.AppendFormat("}}\r\n");
}
}
string ProcessJsTypeToXml(Type oType, string sVal)
void ProcessJsTypeToXml(StringBuilder sb, string sName, Type oType, string sVal, bool bAttribute)
{
string sRes;
switch (Type.GetTypeCode(oType))
{
case TypeCode.Boolean:
sRes = "getXmlFromBool(" + sVal + ")";
if(bAttribute)
{
sb.AppendFormat("writer.WriteXmlAttributeBool(\"{0}\", {1});\r\n", sName, sVal);
}
else
{
sb.AppendFormat("writer.WriteXmlNodeStart(\"{0}\", true);\r\n", sName);
sb.AppendFormat("writer.WriteXmlBool({0});\r\n", sVal);
sb.AppendFormat("writer.WriteXmlNodeEnd(\"{0}\");\r\n", sName);
}
break;
case TypeCode.Byte:
case TypeCode.SByte:
......@@ -700,11 +742,30 @@ namespace codegen
case TypeCode.UInt64:
case TypeCode.Single:
case TypeCode.Double:
sRes = sVal + ".toString()";
if (bAttribute)
{
sb.AppendFormat("writer.WriteXmlAttributeNumber(\"{0}\", {1});\r\n", sName, sVal);
}
else
{
sb.AppendFormat("writer.WriteXmlNodeStart(\"{0}\", true);\r\n", sName);
sb.AppendFormat("writer.WriteXmlNumber({0});\r\n", sVal);
sb.AppendFormat("writer.WriteXmlNodeEnd(\"{0}\");\r\n", sName);
}
break;
default:
if (bAttribute)
{
sb.AppendFormat("writer.WriteXmlAttributeString(\"{0}\", {1});\r\n", sName, sVal);
}
else
{
sb.AppendFormat("writer.WriteXmlNodeStart(\"{0}\", true);\r\n", sName);
sb.AppendFormat("writer.WriteXmlString({0});\r\n", sVal);
sb.AppendFormat("writer.WriteXmlNodeEnd(\"{0}\");\r\n", sName);
}
break;
default: sRes = sVal; break;
}
return sRes;
}
string getNameWithPrefix(GenClassPivot oGenClass, GenMemberPivot oGenMember)
......
......@@ -568,7 +568,7 @@
<xsd:attribute name="optimizeMemory" type="xsd:boolean" use="optional" default="false"/>
<xsd:attribute name="enableRefresh" type="xsd:boolean" use="optional" default="true"/>
<xsd:attribute name="refreshedBy" type="s:ST_Xstring" use="optional"/>
<xsd:attribute name="refreshedDateIso" type="xsd:dateTime" use="optional"/>
<xsd:attribute name="refreshedDate" type="xsd:double" use="optional"/>
<xsd:attribute name="backgroundQuery" type="xsd:boolean" default="false"/>
<xsd:attribute name="missingItemsLimit" type="xsd:unsignedInt" use="optional"/>
<xsd:attribute name="createdVersion" type="xsd:unsignedByte" use="optional" default="0"/>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment