int ObserverPlugin::QueryArchives(const TCHAR* lpFileName, Array<ArchiveQueryResult*>& result) { StorageGeneralInfo info; HANDLE hArchive = OpenStorage(lpFileName, &info); if ( hArchive ) { CloseStorage(hArchive); ArchiveQueryResult* pResult = new ArchiveQueryResult; pResult->uidFormat = m_pFormatInfo->uid; pResult->uidPlugin = m_uid; result.add(pResult); return 1; } return 0; }
bool SettingsXML::OpenStorage(uint access, wchar_t (&szErr)[512]) { bool bRc = false; bool bNeedReopen = (mp_File == NULL); LPCWSTR pszXmlFile; HRESULT hr = S_OK; VARIANT_BOOL bSuccess; IXMLDOMParseError* pErr = NULL; VARIANT vt; VariantInit(&vt); bool bAllowCreate = (access & KEY_WRITE) == KEY_WRITE; szErr[0] = 0; if (m_Storage.pszFile && *m_Storage.pszFile) { pszXmlFile = m_Storage.pszFile; } else { // Must be already initialized _ASSERTE(m_Storage.pszFile && *m_Storage.pszFile); pszXmlFile = gpConEmu->ConEmuXml(); if (!pszXmlFile || !*pszXmlFile) { goto wrap; } } m_Storage.pszFile = pszXmlFile; // Changed access type? if (bNeedReopen || (mn_access != access)) { DWORD dwAccess = GENERIC_READ; DWORD dwMode = OPEN_EXISTING; if ((access & KEY_WRITE) == KEY_WRITE) { dwAccess |= GENERIC_WRITE; dwMode = OPEN_ALWAYS; } HANDLE hFile = CreateFile(pszXmlFile, dwAccess, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, dwMode, 0, 0); // XML-файл отсутсвует if (!hFile || (hFile == INVALID_HANDLE_VALUE)) { goto wrap; } else { BY_HANDLE_FILE_INFORMATION bfi = {0}; if (GetFileInformationByHandle(hFile, &bfi)) { mb_Empty = (bfi.nFileSizeHigh == 0 && bfi.nFileSizeLow == 0); if (!mb_Empty) { // UTF-8 BOM? Xml DOM does not allows BOM if (bfi.nFileSizeHigh == 0 && bfi.nFileSizeLow == 3) { BYTE bom[3] = {}; DWORD nRead = 0; if (ReadFile(hFile, bom, sizeof(bom), &nRead, NULL) && (nRead == sizeof(bom)) && (bom[0]==0xEF && bom[1]==0xBB && bom[2]==0xBF)) { mb_Empty = true; } } } } CloseHandle(hFile); hFile = NULL; if (mb_Empty && bAllowCreate) { bNeedReopen = true; hFile = CreateFile(pszXmlFile, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, 0, 0); if (!hFile || (hFile == INVALID_HANDLE_VALUE)) { goto wrap; } else { LPCSTR pszDefault = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" "<key name=\"Software\">\r\n" "\t<key name=\"ConEmu\">\r\n" "\t</key>\r\n" "</key>\r\n"; DWORD nLen = lstrlenA(pszDefault); WriteFile(hFile, pszDefault, nLen, &nLen, NULL); CloseHandle(hFile); } hFile = NULL; } } } if (!bNeedReopen) { bRc = true; goto wrap; } if (mb_Empty && !bAllowCreate) goto wrap; CloseStorage(); SAFETRY { _ASSERTE(mp_File == NULL); mp_File = CreateDomDocument(szErr, countof(szErr)); if (FAILED(hr) || !mp_File) { //Ошибка уже в szErr //_wsprintf(szErr, SKIPLEN(countof(szErr)) L"Can't create IID_IXMLDOMDocument!\nErrCode=0x%08X", (DWORD)hr); goto wrap; } hr = mp_File->put_preserveWhiteSpace(VARIANT_TRUE); hr = mp_File->put_async(VARIANT_FALSE); // Загрузить xml-ку bSuccess = VARIANT_FALSE; vt.vt = VT_BSTR; vt.bstrVal = ::SysAllocString(pszXmlFile); hr = mp_File->load(vt, &bSuccess); VariantClear(&vt); if (hr == S_FALSE) { mb_Empty = true; // Файл пуст (может только заголовок?) } else if (FAILED(hr) || !bSuccess) { _wsprintf(szErr, SKIPLEN(countof(szErr)) L"Failed to load ConEmu.xml!\nHR=0x%08X\n", (DWORD)hr); hr = mp_File->get_parseError(&pErr); if (pErr) { long errorCode = 0; // Contains the error code of the last parse error. Read-only. long line = 0; // Specifies the line number that contains the error. Read-only. long linepos = 0; // Contains the character position within the line where the error occurred. Read-only. hr = pErr->get_errorCode(&errorCode); hr = pErr->get_line(&line); hr = pErr->get_linepos(&linepos); wsprintf(szErr+_tcslen(szErr), L"XmlErrCode=%i, Line=%i, Pos=%i", errorCode, line, linepos); } goto wrap; } mn_access = access; bRc = true; } SAFECATCH { lstrcpy(szErr, L"Exception in SettingsXML::OpenStorage"); bRc = false; } wrap: SafeRelease(pErr); if (!bRc) CloseStorage(); return bRc; }
SettingsXML::~SettingsXML() { CloseStorage(); }