bool pws_os::RegDeleteEntry(const TCHAR *name) { HKEY hSubkey; DWORD dwResult, dwType; bool bRetVal; // Keys in registry are in: // "HKEY_CURRENT_USER\Software\Password Safe\Password Safe\" const stringT csSubkey = _T("Software\\") + stringT(::AfxGetApp()->m_pszRegistryKey) + _T("\\") + stringT(::AfxGetApp()->m_pszRegistryKey); dwResult = RegOpenKeyEx(HKEY_CURRENT_USER, csSubkey.c_str(), NULL, KEY_ALL_ACCESS, &hSubkey); if (dwResult != ERROR_SUCCESS) return false; // may have been called due to OldPrefs dwResult = RegQueryValueEx(hSubkey, name, NULL, &dwType, NULL, NULL); if (dwResult == ERROR_SUCCESS) { // Was there - now delete it dwResult = RegDeleteValue(hSubkey, name); ASSERT(dwResult == ERROR_SUCCESS); bRetVal = (dwResult == ERROR_SUCCESS); } else bRetVal = true; dwResult = RegCloseKey(hSubkey); ASSERT(dwResult == ERROR_SUCCESS); return bRetVal; }
bool CXMLprefs::RemoveHostnameUsername(const stringT &sHost, const stringT &sUser, bool &bNoMoreNodes) { // If all OK, after removal of supplied hostname/username, then // bNoMoreNodes indicates if there still remain more nodes (hostname/username) // in the configuration file bNoMoreNodes = false; // Validate parameters if (sHost.empty() || sUser.empty()) return false; if (m_pXMLDoc == NULL) return false; stringT sPath = stringT(_T("Pwsafe_Settings//")) + sHost; pugi::xml_node node = m_pXMLDoc->first_element_by_path(sPath.c_str(), _T('\\')); if (node == NULL) return false; if (!node.remove_child(sUser.c_str())) return false; // Check if more children bNoMoreNodes = node.first_child() == NULL; return true; }
stringT pws_os::getsafedir(void) { stringT sDrive, sDir, sName, sExt, retval; pws_os::splitpath(getexecdir(), sDrive, sDir, sName, sExt); const stringT sDriveT = sDrive + _T("\\"); // Trailing slash required. const UINT uiDT = ::GetDriveType(sDriveT.c_str()); if (uiDT == DRIVE_REMOVABLE) { stringT::size_type index = sDir.rfind(_T("Program\\")); if (index != stringT::npos) { sDir.replace(index, 8, stringT(_T("Safes\\"))); retval = sDrive + sDir; if (PathFileExists(retval.c_str()) == TRUE) return retval; } } stringT sLocalSafePath; if (GetLocalDir(CSIDL_PERSONAL, sLocalSafePath)) { retval = sLocalSafePath + _T("\\My Safes"); if (PathFileExists(retval.c_str()) == FALSE) if (_tmkdir(retval.c_str()) != 0) retval = _T(""); // couldn't create dir!? } return retval; }
XMLFileValidation::XMLFileValidation() { for (int i = 0; i < XLE_ELEMENTS; i++) { m_element_map.insert(file_element_pair(stringT(m_file_elements[i].name), m_file_elements[i].file_element_data)); } }
stringT pws_os::getexecdir() { // returns the directory part of ::GetModuleFileName() TCHAR acPath[MAX_PATH + 1]; if (GetModuleFileName(NULL, acPath, MAX_PATH + 1) != 0) { // guaranteed file name of at least one character after path '\' *(_tcsrchr(acPath, _T('\\')) + 1) = _T('\0'); } else { acPath[0] = TCHAR('\\'); acPath[1] = TCHAR('\0'); } return stringT(acPath); }
bool pws_os::RegCheckExists(const TCHAR *stree) { if (stree == NULL) stree = ::AfxGetApp()->m_pszRegistryKey; const stringT csSubkey = _T("Software\\") + stringT(stree); HKEY hSubkey; bool bExists = ::RegOpenKeyEx(HKEY_CURRENT_USER, csSubkey.c_str(), 0L, KEY_READ, &hSubkey) == ERROR_SUCCESS; if (bExists) ::RegCloseKey(hSubkey); return bExists; }
void pws_os::Logit(LPCTSTR lpszFormat, ...) { va_list args; va_start(args, lpszFormat); TCHAR szBuffer[1024]; int nBuf = _vsntprintf_s(szBuffer, sizeof(szBuffer) / sizeof(TCHAR), _TRUNCATE, lpszFormat, args); #ifdef DEBUG ASSERT(nBuf > 0); #else UNREFERENCED_PARAMETER(nBuf); // In Release build only otherwise MS Compiler warning #endif PWSLog::GetLog()->Add(stringT(szBuffer)); va_end(args); }
bool pws_os::RegCheckExists(const TCHAR *stree) { if (stree == NULL) { CWinApp *app = ::AfxGetApp(); if (app == NULL) // can happen in unit test framework return false; stree = app->m_pszRegistryKey; } const stringT csSubkey = _T("Software\\") + stringT(stree); HKEY hSubkey; bool bExists = ::RegOpenKeyEx(HKEY_CURRENT_USER, csSubkey.c_str(), 0L, KEY_READ, &hSubkey) == ERROR_SUCCESS; if (bExists) ::RegCloseKey(hSubkey); return bExists; }
stringT pws_os::getxmldir(void) { stringT sDrive, sDir, sName, sExt; pws_os::splitpath(getexecdir(), sDrive, sDir, sName, sExt); const stringT sDriveT = sDrive + _T("\\"); // Trailing slash required. const UINT uiDT = ::GetDriveType(sDriveT.c_str()); if (uiDT == DRIVE_REMOVABLE) { stringT::size_type index = sDir.rfind(_T("Program\\")); if (index != stringT::npos) { sDir.replace(index, 8, stringT(_T("xml\\"))); stringT retval = sDrive + sDir; if (PathFileExists(retval.c_str()) == TRUE) return retval; } } return getexecdir(); }
/* * GetStringTFromURLRef * * Converts a URLRef (something on the filesystem, as far as this file is concerned) to a * wchar_t string without making any assumptions about the encoding of CFURLRef * */ static stringT GetStringTFromURLRef(CFURLRef url) { stringT retval; CFStringRef cfpath = CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle); if (cfpath) { CFIndex numChars = CFStringGetLength(cfpath); wchar_t* wPath = new wchar_t[numChars+1]; //any alignment issues? CFIndex numBytesWritten = 0; assert(sizeof(wchar_t) == 4); //kCFStringEncodingUTF32 hardcoded below CFIndex numConverted = CFStringGetBytes(cfpath, CFRangeMake(0, numChars), kCFStringEncodingUTF32, 0, false, reinterpret_cast<UInt8 *>(wPath), sizeof(wchar_t) * numChars, &numBytesWritten); assert(static_cast<CFIndex>(numConverted*sizeof(wchar_t)) == numBytesWritten); retval = stringT(wPath, numConverted); delete [] wPath; CFRelease(cfpath); } return retval; }
void pws_os::Logit(LPCTSTR lpszFormat, ...) { va_list args; va_start(args, lpszFormat); TCHAR *szbuffer = 0; int nwritten, len = STARTING_LOG_STATEMENT; do { len *= 2; delete [] szbuffer; szbuffer = new TCHAR[len + 1]; memset(szbuffer, 0, sizeof(TCHAR) * (len + 1)); nwritten = vstprintf(szbuffer, len, lpszFormat, args); //apple's documentation doesn't say if nwritten is +ve, -ve, 0 or if errno is set in case of overflow } while(!(nwritten > 0 && nwritten < len) && len <= MAX_LOG_STATEMENT); PWSLog::GetLog()->Add(stringT(szbuffer)); delete[] szbuffer; va_end(args); }
// --------------------------------------------------------------------------- bool XFileXMLProcessor::Process(const bool &bvalidation, const stringT &ImportedPrefix, const stringT &strXMLFileName, const stringT &strXSDFileName, const bool &bImportPSWDsOnly) { USES_XMLCH_STR bool bErrorOccurred = false; bool b_into_empty = false; stringT cs_validation; LoadAString(cs_validation, IDSC_XMLVALIDATION); stringT cs_import; LoadAString(cs_import, IDSC_XMLIMPORT); stringT strResultText(_T("")); m_bValidation = bvalidation; // Validate or Import XSecMemMgr sec_mm; // Initialize the XML4C2 system try { XMLPlatformUtils::Initialize(XMLUni::fgXercescDefaultLocale, 0, 0, &sec_mm); } catch (const XMLException& toCatch) { strResultText = stringT(_X2ST(toCatch.getMessage())); return false; } const XMLCh* xmlfilename = _W2X(strXMLFileName.c_str()); const XMLCh* schemafilename = _W2X(strXSDFileName.c_str()); // Create a SAX2 parser object. SAX2XMLReader* pSAX2Parser = XMLReaderFactory::createXMLReader(&sec_mm); // Set non-default features pSAX2Parser->setFeature(XMLUni::fgSAX2CoreNameSpacePrefixes, true); pSAX2Parser->setFeature(XMLUni::fgSAX2CoreValidation, true); pSAX2Parser->setFeature(XMLUni::fgXercesDynamic, false); pSAX2Parser->setFeature(XMLUni::fgXercesSchemaFullChecking, true); pSAX2Parser->setFeature(XMLUni::fgXercesLoadExternalDTD, false); pSAX2Parser->setFeature(XMLUni::fgXercesSkipDTDValidation, true); // Set properties pSAX2Parser->setProperty(XMLUni::fgXercesScannerName, const_cast<void*>(reinterpret_cast<const void*>(XMLUni::fgSGXMLScanner))); pSAX2Parser->setInputBufferSize(4096); // Set schema file name (also via property) pSAX2Parser->setProperty(XMLUni::fgXercesSchemaExternalNoNameSpaceSchemaLocation, const_cast<void*>(reinterpret_cast<const void*>(schemafilename))); // Create SAX handler object and install it on the pSAX2Parser, as the // document and error pSAX2Handler. XFileSAX2Handlers * pSAX2Handler = new XFileSAX2Handlers; pSAX2Parser->setContentHandler(pSAX2Handler); pSAX2Parser->setErrorHandler(pSAX2Handler); pSAX2Handler->SetVariables(m_bValidation ? NULL : m_pXMLcore, m_bValidation, ImportedPrefix, m_delimiter, bImportPSWDsOnly, m_bValidation ? NULL : m_pPossible_Aliases, m_bValidation ? NULL : m_pPossible_Shortcuts, m_pmulticmds, m_prpt); if (!m_bValidation) { b_into_empty = m_pXMLcore->GetNumEntries() == 0; } try { // Let's begin the parsing now pSAX2Parser->parse(xmlfilename); } catch (const OutOfMemoryException&) { LoadAString(strResultText, IDCS_XERCESOUTOFMEMORY); bErrorOccurred = true; } catch (const XMLException& e) { strResultText = stringT(_X2ST(e.getMessage())); bErrorOccurred = true; } catch (...) { LoadAString(strResultText, IDCS_XERCESEXCEPTION); bErrorOccurred = true; } if (pSAX2Handler->getIfErrors() || bErrorOccurred) { bErrorOccurred = true; strResultText = pSAX2Handler->getValidationResult(); Format(m_strXMLErrors, IDSC_XERCESPARSEERROR, m_bValidation ? cs_validation.c_str() : cs_import.c_str(), strResultText.c_str()); } else { if (m_bValidation) { m_strXMLErrors = pSAX2Handler->getValidationResult(); m_numEntriesValidated = pSAX2Handler->getNumEntries(); m_delimiter = pSAX2Handler->getDelimiter(); } else { pSAX2Handler->AddXMLEntries(); // Get numbers (may have been modified by AddXMLEntries m_numEntriesImported = pSAX2Handler->getNumEntries(); m_numEntriesSkipped = pSAX2Handler->getNumSkipped(); m_numEntriesRenamed = pSAX2Handler->getNumRenamed(); m_numEntriesPWHErrors = pSAX2Handler->getNumPWHErrors(); m_numNoPolicies = pSAX2Handler->getNumNoPolicies(); m_numRenamedPolicies = pSAX2Handler->getNumRenamedPolicies(); m_numShortcutsRemoved = pSAX2Handler->getNumShortcutsRemoved(); // Get lists m_strXMLErrors = pSAX2Handler->getXMLErrors(); m_strSkippedList = pSAX2Handler->getSkippedList(); m_strPWHErrorList = pSAX2Handler->getPWHErrorList(); m_strRenameList = pSAX2Handler->getRenameList(); if (b_into_empty) { pSAX2Handler->AddDBPreferences(); } } } // Delete the pSAX2Parser itself. Must be done prior to calling Terminate, below. delete pSAX2Parser; delete pSAX2Handler; USES_XMLCH_STR_END // And call the termination method XMLPlatformUtils::Terminate(); return !bErrorOccurred; }
bool XFilterXMLProcessor::Process(const bool &bvalidation, const StringX &strXMLData, const stringT &strXMLFileName, const stringT &strXSDFileName) { USES_XMLCH_STR bool bErrorOccurred = false; stringT cs_validation; LoadAString(cs_validation, IDSC_XMLVALIDATION); stringT cs_import; LoadAString(cs_import, IDSC_XMLIMPORT); stringT strResultText(_T("")); m_bValidation = bvalidation; // Validate or Import XSecMemMgr sec_mm; // Initialize the XML4C2 system try { XMLPlatformUtils::Initialize(XMLUni::fgXercescDefaultLocale, 0, 0, &sec_mm); } catch (const XMLException& toCatch) { #ifdef UNICODE m_strXMLErrors = stringT(_X2ST(toCatch.getMessage())); #else char *szData = XMLString::transcode(toCatch.getMessage()); strResultText = stringT(szData); XMLString::release(&szData); #endif return false; } // Create a SAX2 parser object. SAX2XMLReader* pSAX2Parser = XMLReaderFactory::createXMLReader(&sec_mm); // Set non-default features pSAX2Parser->setFeature(XMLUni::fgSAX2CoreNameSpacePrefixes, true); pSAX2Parser->setFeature(XMLUni::fgSAX2CoreValidation, true); pSAX2Parser->setFeature(XMLUni::fgXercesSchemaFullChecking, true); pSAX2Parser->setFeature(XMLUni::fgXercesLoadExternalDTD, false); pSAX2Parser->setFeature(XMLUni::fgXercesSkipDTDValidation, true); // Set properties pSAX2Parser->setProperty(XMLUni::fgXercesSchemaExternalNoNameSpaceSchemaLocation, (void *)strXSDFileName.c_str()); pSAX2Parser->setProperty(XMLUni::fgXercesScannerName, (void *)XMLUni::fgSGXMLScanner); pSAX2Parser->setInputBufferSize(4096); // Create SAX handler object and install it on the pSAX2Parser, as the // document and error pSAX2Handler. XFilterSAX2Handlers * pSAX2Handler = new XFilterSAX2Handlers; pSAX2Parser->setContentHandler(pSAX2Handler); pSAX2Parser->setErrorHandler(pSAX2Handler); // Workaround/bypass until Xerces supports retrieving version from the // <xs:schema ...> statement! // Set 'dummy' schema version to arbitrary value > 1 pSAX2Handler->SetSchemaVersion(99); pSAX2Handler->SetVariables(m_pAsker, &m_MapFilters, m_FPool, m_bValidation); try { // Let's begin the parsing now if (!strXMLFileName.empty()) { pSAX2Parser->parse(_W2X(strXMLFileName.c_str())); } else { const char *szID = "database_filters"; #ifdef UNICODE const char *buffer = XMLString::transcode(_W2X(strXMLData.c_str())); #else const char *buffer = strXMLData.c_str(); #endif MemBufInputSource* memBufIS = new MemBufInputSource( (const XMLByte*)buffer, strXMLData.length(), szID, false); pSAX2Parser->parse(*memBufIS); delete memBufIS; #ifdef UNICODE XMLString::release((char **)&buffer); #endif } } catch (const OutOfMemoryException&) { LoadAString(strResultText, IDCS_XERCESOUTOFMEMORY); bErrorOccurred = true; } catch (const XMLException& e) { #ifdef UNICODE strResultText = stringT(_X2ST(e.getMessage())); #else char *szData = XMLString::transcode(e.getMessage()); strResultText = stringT(szData); XMLString::release(&szData); #endif bErrorOccurred = true; } catch (...) { LoadAString(strResultText, IDCS_XERCESEXCEPTION); bErrorOccurred = true; } if (pSAX2Handler->getIfErrors() || bErrorOccurred) { bErrorOccurred = true; strResultText = pSAX2Handler->getValidationResult(); Format(m_strXMLErrors, IDSC_XERCESPARSEERROR, m_bValidation ? cs_validation.c_str() : cs_import.c_str(), strResultText.c_str()); } else { m_strXMLErrors = strResultText; } // Delete the pSAX2Parser itself. Must be done prior to calling Terminate, below. delete pSAX2Parser; delete pSAX2Handler; USES_XMLCH_STR_END // And call the termination method XMLPlatformUtils::Terminate(); return !bErrorOccurred; }
const stringT pws_os::RegReadValue(const TCHAR *, const TCHAR *, const TCHAR *value) { return stringT(value); }
void PasswordSafeSearch::FindMatches(const StringX& searchText, bool fCaseSensitive, SearchPointer& searchPtr, const CItemData::FieldBits& bsFields, bool fUseSubgroups, const wxString& subgroupText, CItemData::FieldType subgroupObject, PWSMatch::MatchRule subgroupFunction, bool subgroupFunctionCaseSensitive, Iter begin, Iter end, Accessor afn) { if (searchText.empty()) return; searchPtr.Clear(); typedef StringX (CItemData::*ItemDataFuncT)() const; struct { CItemData::FieldType type; ItemDataFuncT func; } ItemDataFields[] = { {CItemData::GROUP, &CItemData::GetGroup}, {CItemData::TITLE, &CItemData::GetTitle}, {CItemData::USER, &CItemData::GetUser}, {CItemData::PASSWORD, &CItemData::GetPassword}, // {CItemData::NOTES, &CItemData::GetNotes}, {CItemData::URL, &CItemData::GetURL}, {CItemData::EMAIL, &CItemData::GetEmail}, {CItemData::RUNCMD, &CItemData::GetRunCommand}, {CItemData::AUTOTYPE, &CItemData::GetAutoType}, {CItemData::XTIME_INT, &CItemData::GetXTimeInt}, }; for ( Iter itr = begin; itr != end; ++itr) { const int fn = (subgroupFunctionCaseSensitive? -subgroupFunction: subgroupFunction); if (fUseSubgroups && !afn(itr).Matches(stringT(subgroupText.c_str()), subgroupObject, fn)) continue; bool found = false; for (size_t idx = 0; idx < NumberOf(ItemDataFields) && !found; ++idx) { if (bsFields.test(ItemDataFields[idx].type)) { const StringX str = (afn(itr).*ItemDataFields[idx].func)(); found = fCaseSensitive? str.find(searchText) != StringX::npos: FindNoCase(searchText, str); } } if (!found && bsFields.test(CItemData::NOTES)) { StringX str = afn(itr).GetNotes(); found = fCaseSensitive? str.find(searchText) != StringX::npos: FindNoCase(searchText, str); } if (!found && bsFields.test(CItemData::PWHIST)) { size_t pwh_max, err_num; PWHistList pwhistlist; CreatePWHistoryList(afn(itr).GetPWHistory(), pwh_max, err_num, pwhistlist, PWSUtil::TMC_XML); for (PWHistList::iterator iter = pwhistlist.begin(); iter != pwhistlist.end(); iter++) { PWHistEntry pwshe = *iter; found = fCaseSensitive? pwshe.password.find(searchText) != StringX::npos: FindNoCase(searchText, pwshe.password ); if (found) break; // break out of for loop } pwhistlist.clear(); } if (found) { uuid_array_t uuid; afn(itr).GetUUID(uuid); searchPtr.Add(pws_os::CUUID(uuid)); } } }
StringX PWSRun::getruncmd(const StringX &sxFile, bool &bfound) const { // 1. If first parameter is in quotes - assume fully qualified - don't search. // 2. If first parameter starts with '%, assume it is going to be replaced by the // corresponding environmental variable - no need to search directories. // 3. If the first parameter ends in '.xxx', and '.xxx' is in the PATHEXT variable, // search for it as-is. If not, append each of the known extensions to it and then // search. // 4. If searched and could not find, just issue 'as-is'. std::vector<StringX> vpaths; std::vector<StringX> vextns; StringX full_pgm(sxFile), sx_cwd; StringX sx_temp, sx_dirs, sx_extns; stringT path, drive, dir, fname, extn; stringT s_temp; bool bsearch_dirs(true), bsearch_extns(true); const StringX::size_type len = full_pgm.length(); bfound = false; if (len == 0) return full_pgm; // Search order: // Current working directory s_temp = pws_os::getcwd(); stringT::size_type Tlen = s_temp.length(); if (Tlen == 0 || s_temp[Tlen - 1] != _T('\\')) { s_temp += _T("\\"); } sx_cwd = StringX(s_temp.c_str()); vpaths.push_back(sx_cwd); // Windows directory s_temp = pws_os::getenv("windir", true); if (s_temp.length() > 0) vpaths.push_back(StringX(s_temp.c_str())); // Windows/System32 directory if (!s_temp.empty()) { s_temp += stringT(_T("System32")); vpaths.push_back(StringX(s_temp.c_str())); } // Directories in PATH s_temp = pws_os::getenv("PATH", true); sx_temp = s_temp.c_str(); // tokenize into separate elements using ; as the field separator for (StringX::size_type st_startpos = 0; st_startpos < sx_temp.size(); /* st_startpos advanced in body */) { StringX::size_type st_next = sx_temp.find(_T(';'), st_startpos); if (st_next == StringX::npos) st_next = sx_temp.size(); if (st_next > 0) { sx_dirs = sx_temp.substr(st_startpos, st_next - st_startpos); vpaths.push_back(sx_dirs); } st_startpos = st_next + 1; // too complex for for statement } // tokenization for loop // Apps Paths registry key - see below // Get support program extensions s_temp = pws_os::getenv("PATHEXT", false); sx_temp = s_temp.c_str(); // tokenize into separate elements using ; as the field separator for (StringX::size_type st_startpos = 0; st_startpos < sx_temp.size(); /* st_startpos advanced in body */) { StringX::size_type st_next = sx_temp.find(_T(';'), st_startpos); if (st_next == StringX::npos) st_next = sx_temp.size(); if (st_next > 0) { sx_extns = sx_temp.substr(st_startpos, st_next - st_startpos); for(StringX::size_type i = 1; i < sx_extns.size(); i++) { sx_extns[i] = _totlower(sx_extns[i]); } vextns.push_back(sx_extns); } st_startpos = st_next + 1; // too complex for for statement } // tokenization for loop // Just need drive, directory and file extension path = full_pgm.c_str(); pws_os::splitpath(path, drive, dir, fname, extn); if (!extn.empty()) { // ends with '.x-x' StringX sx_temp = StringX(extn.c_str()); for (StringX::size_type i = 1; i < extn.size(); i++) { sx_temp[i] = _totlower(sx_temp[i]); } // Check if a known command extn if (std::find(vextns.begin(), vextns.end(), sx_temp) != vextns.end()) { bsearch_extns = false; } } if (!drive.empty() || !dir.empty()) { // Don't search directories but do search extensions bsearch_dirs = false; if (drive.empty()) { // Drive not specified - so could be relative to current directory sx_temp = sx_cwd + full_pgm; if (pws_os::FileExists(sx_temp.c_str())) { full_pgm = sx_temp; bfound = true; goto exit; } // Doesn't exist - add on know program extensions for (StringX::size_type ie = 0; ie < vextns.size(); ie++) { sx_extns = vextns[ie]; if (pws_os::FileExists((sx_temp + sx_extns).c_str())) { full_pgm = full_pgm + sx_extns; bfound = true; goto exit; } } } else { // Drive specified - so should be full path. // Check if file exists as-is if (pws_os::FileExists(full_pgm.c_str())) { bfound = true; goto exit; } // Doesn't exist - add on know program extensions for (StringX::size_type ie = 0; ie < vextns.size(); ie++) { sx_extns = vextns[ie]; if (pws_os::FileExists((full_pgm + sx_extns).c_str())) { full_pgm = full_pgm + sx_extns; bfound = true; goto exit; } } } } // Now search directories! if (bsearch_dirs) { // Ensure directory ends in a '/' for (StringX::size_type id = 0; id < vpaths.size(); id++) { sx_dirs = vpaths[id]; if (sx_dirs[sx_dirs.length() - 1] != _T('\\')) sx_dirs += _T("\\"); if (bsearch_extns) { for (StringX::size_type ie = 0; ie < vextns.size(); ie++) { sx_extns = vextns[ie]; if (pws_os::FileExists((sx_dirs + full_pgm + sx_extns).c_str())) { full_pgm = sx_dirs + full_pgm + sx_extns; bfound = true; goto exit; } } } else { if (pws_os::FileExists(stringT((sx_dirs + full_pgm).c_str()))) { full_pgm = sx_dirs + full_pgm; bfound = true; goto exit; } } } } // If not found directly or within current directory structure, // we so need to search registry. // Either: we had to search extensions - // so full_pgm does not end with known program extn; // Or: we didn't have to search - // so full_pgm may end with '.exe' and we must not add if (!bfound && (bsearch_extns || (!bsearch_extns && extn == _T(".exe")))) { // Check via registry if (bsearch_extns) full_pgm += _T(".exe"); // Look for registry key bool bexists; HKEY hSubkey; StringX csSubkey = StringX(_T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\")) + full_pgm; bexists = (::RegOpenKeyEx(HKEY_LOCAL_MACHINE, csSubkey.c_str(), 0L, KEY_READ, &hSubkey) == ERROR_SUCCESS); if (bexists) { LONG rv; DWORD dwType, dwDataLen(0); rv = ::RegQueryValueEx(hSubkey, _T("Path"), NULL, &dwType, NULL, &dwDataLen); if (rv == ERROR_SUCCESS && dwType == REG_SZ) { dwDataLen++; TCHAR *pData = new TCHAR[dwDataLen]; ::memset(pData, 0, dwDataLen); rv = ::RegQueryValueEx(hSubkey, _T("Path"), NULL, &dwType, LPBYTE(pData), &dwDataLen); if (rv == ERROR_SUCCESS) { sx_temp = pData; StringX::size_type len = sx_temp.length(); if (sx_temp[len - 1] == _T(';')) sx_temp = sx_temp.substr(0, len - 1) + _T('\\'); else if (sx_temp[len - 1] != _T('\\') && sx_temp[len - 1] != _T('/')) sx_temp = sx_temp + _T('\\'); full_pgm = sx_temp + full_pgm; bfound = true; } delete[] pData; } // Get the value ::RegCloseKey(hSubkey); } } exit: return full_pgm; }
bool XFilterXMLProcessor::Process(const bool &bvalidation, const StringX &strXMLData, const stringT &strXMLFileName, const stringT &strXSDFileName) { USES_XMLCH_STR bool bErrorOccurred = false; stringT cs_validation; LoadAString(cs_validation, IDSC_XMLVALIDATION); stringT cs_import; LoadAString(cs_import, IDSC_XMLIMPORT); stringT strResultText(_T("")); m_bValidation = bvalidation; // Validate or Import XSecMemMgr sec_mm; // Initialize the XML4C2 system try { XMLPlatformUtils::Initialize(XMLUni::fgXercescDefaultLocale, 0, 0, &sec_mm); } catch (const XMLException& toCatch) { m_strXMLErrors = stringT(_X2ST(toCatch.getMessage())); return false; } // Create a SAX2 parser object. SAX2XMLReader* pSAX2Parser = XMLReaderFactory::createXMLReader(&sec_mm); // Set non-default features pSAX2Parser->setFeature(XMLUni::fgSAX2CoreNameSpacePrefixes, true); pSAX2Parser->setFeature(XMLUni::fgSAX2CoreValidation, true); pSAX2Parser->setFeature(XMLUni::fgXercesSchemaFullChecking, true); pSAX2Parser->setFeature(XMLUni::fgXercesLoadExternalDTD, false); pSAX2Parser->setFeature(XMLUni::fgXercesSkipDTDValidation, true); // Set properties // we need const_cast here, because _W2X return const wchar_t* when // WCHAR_INCOMPATIBLE_XMLCH isn't set pSAX2Parser->setProperty(XMLUni::fgXercesSchemaExternalNoNameSpaceSchemaLocation, const_cast<XMLCh*>(_W2X(strXSDFileName.c_str()))); pSAX2Parser->setProperty(XMLUni::fgXercesScannerName, const_cast<XMLCh*>(XMLUni::fgSGXMLScanner)); pSAX2Parser->setInputBufferSize(4096); // Create SAX handler object and install it on the pSAX2Parser, as the // document and error pSAX2Handler. XFilterSAX2Handlers * pSAX2Handler = new XFilterSAX2Handlers; pSAX2Parser->setContentHandler(pSAX2Handler); pSAX2Parser->setErrorHandler(pSAX2Handler); // Workaround/bypass until Xerces supports retrieving version from the // <xs:schema ...> statement! // Set 'dummy' schema version to arbitrary value > 1 pSAX2Handler->SetSchemaVersion(99); pSAX2Handler->SetVariables(m_pAsker, &m_MapFilters, m_FPool, m_bValidation); // instantiate converter out of if/else to be sure that string will be valid // till the end of pSAX2Parser, that may capture pointer to string from MemBufInputSource CUTF8Conv conv; try { // Let's begin the parsing now if (!strXMLFileName.empty()) { pSAX2Parser->parse(_W2X(strXMLFileName.c_str())); } else { const char *szID = "database_filters"; // Xerces use encoding from XML (we have set it to utf-8), but transcode() on Windows convert to one-byte cpXXXX, // so we need to manually convert from wchar to UTF-8 const unsigned char* buffer=nullptr; size_t len; if (!conv.ToUTF8(strXMLData, buffer, len)) { throw std::runtime_error("Can't convert data to UTF-8"); } //2nd parameter must be number of bytes, so we use a length for char* representation MemBufInputSource* memBufIS = new MemBufInputSource( reinterpret_cast<const XMLByte *>(buffer), strlen(reinterpret_cast<const char*>(buffer)), szID, false); pSAX2Parser->parse(*memBufIS); delete memBufIS; } } catch (const OutOfMemoryException&) { LoadAString(strResultText, IDCS_XERCESOUTOFMEMORY); bErrorOccurred = true; } catch (const XMLException& e) { strResultText = stringT(_X2ST(e.getMessage())); bErrorOccurred = true; } catch (...) { LoadAString(strResultText, IDCS_XERCESEXCEPTION); bErrorOccurred = true; } if (pSAX2Handler->getIfErrors() || bErrorOccurred) { bErrorOccurred = true; if (pSAX2Handler->getIfErrors()) strResultText = pSAX2Handler->getValidationResult(); Format(m_strXMLErrors, IDSC_XERCESPARSEERROR, m_bValidation ? cs_validation.c_str() : cs_import.c_str(), strResultText.c_str()); } else { m_strXMLErrors = strResultText; } // Delete the pSAX2Parser itself. Must be done prior to calling Terminate, below. delete pSAX2Parser; delete pSAX2Handler; USES_XMLCH_STR_END // And call the termination method XMLPlatformUtils::Terminate(); return !bErrorOccurred; }