[d6386d]: pwsafe / pwsafe / corelib / PWSXML.cpp Maximize Restore History

Download this file

PWSXML.cpp    254 lines (224 with data), 8.0 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
/*
* Copyright (c) 2003-2007 Rony Shapiro <ronys@users.sourceforge.net>.
* All rights reserved. Use of the code is allowed under the
* Artistic License terms, as specified in the LICENSE file
* distributed with this code, or available from
* http://www.opensource.org/licenses/artistic-license.php
*/
// PWSXML.cpp : implementation file
//
#include "PWSXML.h"
#include "SAXHandlers.h"
#include "ItemData.h"
#include "MyString.h"
#include "corelib.h"
#include "PWScore.h"
#include "xml_import.h"
#include "UnknownField.h"
#include <atlcomcli.h>
#ifdef POCKET_PC
#include <wce_types.h>
#include <wce_stat.h>
#else
#include <sys/types.h>
#include <sys/stat.h>
#endif
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
PWSXML::PWSXML() : m_xmlcore(NULL)
{
m_MSXML_Version = 60;
m_delimiter = _T('^');
}
PWSXML::~PWSXML()
{
}
void
PWSXML::SetCore(PWScore *core)
{
m_xmlcore = core;
}
// ---------------------------------------------------------------------------
bool PWSXML::XMLProcess(const bool &bvalidation, const CString &ImportedPrefix,
const CString &strXMLFileName, const CString &strXSDFileName,
int &nITER, int &nRecordsWithUnknownFields, UnknownFieldList &uhfl)
{
HRESULT hr, hr0, hr60, hr40, hr30;
bool b_ok = false;
bool b_into_empty;
const CString cs_validation(MAKEINTRESOURCE(IDSC_XMLVALIDATION));
const CString cs_import(MAKEINTRESOURCE(IDSC_XMLIMPORT));
m_strResultText = _T("");
m_bValidation = bvalidation; // Validate or Import
// Create SAXReader object
ISAXXMLReaderPtr pSAXReader = NULL;
// Get ready for XSD schema validation
IXMLDOMSchemaCollection2Ptr pSchemaCache = NULL;
if (m_bValidation) { //XMLValidate
// Try 60
hr60 = pSAXReader.CreateInstance(__uuidof(SAXXMLReader60), NULL, CLSCTX_ALL);
if (FAILED(hr60)) {
// Try 40
hr40 = pSAXReader.CreateInstance(__uuidof(SAXXMLReader40), NULL, CLSCTX_ALL);
if (FAILED(hr40)) {
// Try 30
hr30 = pSAXReader.CreateInstance(__uuidof(SAXXMLReader30), NULL, CLSCTX_ALL);
if (FAILED(hr30)) {
m_strResultText.LoadString(IDSC_NOXMLREADER);
goto exit;
} else {
m_MSXML_Version = 30;
}
} else {
m_MSXML_Version = 40;
}
} else {
m_MSXML_Version = 60;
}
} else { // XMLImport
b_into_empty = m_xmlcore->GetNumEntries() == 0;
switch (m_MSXML_Version) {
case 60:
hr0 = pSAXReader.CreateInstance(__uuidof(SAXXMLReader60), NULL, CLSCTX_ALL);
break;
case 40:
hr0 = pSAXReader.CreateInstance(__uuidof(SAXXMLReader40), NULL, CLSCTX_ALL);
break;
case 30:
hr0 = pSAXReader.CreateInstance(__uuidof(SAXXMLReader30), NULL, CLSCTX_ALL);
break;
default:
// Should never get here as validate would have sorted it and this doesn't get called if it fails
ASSERT(0);
}
}
// Create ContentHandlerImpl object
PWSSAXContentHandler* pCH = new PWSSAXContentHandler();
if (m_bValidation)
pCH->SetVariables(NULL, m_bValidation, ImportedPrefix, m_delimiter);
else
pCH->SetVariables(m_xmlcore, m_bValidation, ImportedPrefix, m_delimiter);
// Create ErrorHandlerImpl object
PWSSAXErrorHandler* pEH = new PWSSAXErrorHandler();
// Set Content Handler
hr = pSAXReader->putContentHandler(pCH);
// Set Error Handler
hr = pSAXReader->putErrorHandler(pEH);
switch (m_MSXML_Version) {
case 60:
hr = pSchemaCache.CreateInstance(__uuidof(XMLSchemaCache60));
break;
case 40:
hr = pSchemaCache.CreateInstance(__uuidof(XMLSchemaCache40));
break;
case 30:
hr = pSchemaCache.CreateInstance(__uuidof(XMLSchemaCache30));
break;
default:
m_strResultText.LoadString(IDSC_CANTXMLVALIDATE);
goto exit;
}
if (!FAILED(hr)) { // Create SchemaCache
// Initialize the SchemaCache object with the XSD filename
CComVariant cvXSDFileName;
cvXSDFileName.vt = VT_BSTR;
cvXSDFileName.bstrVal = strXSDFileName.AllocSysString();
hr = pSchemaCache->add(L"", cvXSDFileName);
// Set the SAXReader/Schema Cache features and properties
{
/* Documentation is unclear as to what is in which release.
Try them all - if they don't get set, the world will not end!
Common Error codes:
S_OK Operation successful 0x00000000
E_NOTIMPL Not implemented 0x80004001
E_NOINTERFACE No such interface supported 0x80004002
E_ABORT Operation aborted 0x80004004
E_FAIL Unspecified failure 0x80004005
E_INVALIDARG Invalid argument 0x80070057
Normally not supported on a back level MSXMLn.DLL
*/
// Want all validation errors
hr = pSAXReader->putFeature(L"exhaustive-errors", VARIANT_TRUE);
// Don't allow user to override validation by using DTDs
hr = pSAXReader->putFeature(L"prohibit-dtd", VARIANT_TRUE);
// Don't allow user to override validation by using DTDs (2 features)
hr = pSAXReader->putFeature(L"http://xml.org/sax/features/external-general-entities", VARIANT_FALSE);
hr = pSAXReader->putFeature(L"http://xml.org/sax/features/external-parameter-entities", VARIANT_FALSE);
// Want to validate XML file
hr = pSAXReader->putFeature(L"schema-validation", VARIANT_TRUE);
// Ignore any schema specified in the XML file
hr = pSAXReader->putFeature(L"use-schema-location", VARIANT_FALSE);
// Ignore any schema in the XML file
hr = pSAXReader->putFeature(L"use-inline-schema", VARIANT_FALSE);
// Only use the XSD in PWSafe's installation directory!
hr = pSAXReader->putProperty(L"schemas", _variant_t(pSchemaCache.GetInterfacePtr()));
}
// Let's begin the parsing now
wchar_t wcURL[MAX_PATH]={0};
#ifdef _UNICODE
#if _MSC_VER >= 1400
_tcscpy_s(wcURL, MAX_PATH, strXMLFileName);
#else
_tcscpy(wcURL, strXMLFileName);
#endif
#else
#if _MSC_VER >= 1400
size_t numconverted;
mbstowcs_s(&numconverted, wcURL, MAX_PATH, strXMLFileName, _tcslen(strXMLFileName));
#else
mbstowcs(wcURL, strXMLFileName, _tcslen(strXMLFileName));
#endif
#endif
hr = pSAXReader->parseURL(wcURL);
if(!FAILED(hr)) { // Check for parsing errors
if(pEH->bErrorsFound == TRUE) {
m_strResultText = pEH->m_strValidationResult;
} else {
if (m_bValidation) {
m_numEntriesValidated = pCH->m_numEntries;
m_delimiter = pCH->m_delimiter;
} else {
m_numEntriesImported = pCH->m_numEntries;
m_strResultText = pCH->m_strImportErrors; // Maybe import errors (PWHistory field processing)
m_bRecordHeaderErrors = pCH->m_bRecordHeaderErrors;
nRecordsWithUnknownFields = pCH->m_nRecordsWithUnknownFields;
if (b_into_empty) {
m_bDatabaseHeaderErrors = pCH->m_bDatabaseHeaderErrors;
if (pCH->m_nITER > 0)
nITER = pCH->m_nITER;
UnknownFieldList::const_iterator vi_IterUXFE;
for (vi_IterUXFE = pCH->m_ukhxl.begin();
vi_IterUXFE != pCH->m_ukhxl.end();
vi_IterUXFE++) {
UnknownFieldEntry ukxfe = *vi_IterUXFE;
if (ukxfe.st_length > 0) {
uhfl.push_back(ukxfe);
}
}
} else
m_bDatabaseHeaderErrors = false;
}
b_ok = true;
}
} else {
if(pEH->bErrorsFound == TRUE) {
m_strResultText = pEH->m_strValidationResult;
} else {
m_strResultText.Format(IDSC_XMLPARSEERROR, m_MSXML_Version, hr,
m_bValidation ? cs_validation : cs_import);
}
} // End Check for parsing errors
} else {
m_strResultText.Format(IDSC_XMLBADCREATESCHEMA, m_MSXML_Version, hr,
m_bValidation ? cs_validation : cs_import);
} // End Create Schema Cache
exit:
if (pSchemaCache != NULL)
pSchemaCache.Release();
if (pSAXReader != NULL)
pSAXReader.Release();
return b_ok;
}