コード例 #1
0
ファイル: Registry.cpp プロジェクト: huyiice/ConEmu
bool SettingsXML::IsXmlAllowed()
{
	IXMLDOMDocument* pFile = CreateDomDocument();
	if (pFile)
		pFile->Release();
	return (pFile != NULL);
}
コード例 #2
0
ファイル: Registry.cpp プロジェクト: huyiice/ConEmu
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;
}
コード例 #3
0
ファイル: Registry.cpp プロジェクト: mirror/conemu
bool SettingsXML::OpenKey(const wchar_t *regPath, uint access, BOOL abSilent /*= FALSE*/)
{
	_ASSERTE(!gpConEmu->IsResetBasicSettings() || ((access & KEY_WRITE)!=KEY_WRITE));

	bool lbRc = false;
	HRESULT hr = S_OK;
	wchar_t szErr[512]; szErr[0] = 0;
	wchar_t szName[MAX_PATH];
	const wchar_t* psz = NULL;
	VARIANT_BOOL bSuccess;
	IXMLDOMParseError* pErr = NULL;
	//IXMLDOMNodeList* pList = NULL;
	IXMLDOMNode* pKey = NULL;
	IXMLDOMNode* pChild = NULL;
	VARIANT vt; VariantInit(&vt);
	bool bAllowCreate = (access & KEY_WRITE) == KEY_WRITE;
	CloseKey(); // на всякий

	if (!regPath || !*regPath)
	{
		return false;
	}

	HANDLE hFile = NULL;
	DWORD dwAccess = GENERIC_READ;

	if ((access & KEY_WRITE) == KEY_WRITE)
		dwAccess |= GENERIC_WRITE;

	LPCWSTR pszXmlFile;
	if (m_Storage.pszFile && *m_Storage.pszFile)
	{
		pszXmlFile = m_Storage.pszFile;
	}
	else
	{
		_ASSERTE(m_Storage.pszFile && *m_Storage.pszFile);
		m_Storage.pszFile = pszXmlFile = gpConEmu->ConEmuXml();
	}

	if (!pszXmlFile || !*pszXmlFile)
	{
		return false;
	}

	hFile = CreateFile(pszXmlFile, dwAccess, FILE_SHARE_READ|FILE_SHARE_WRITE,
	                   NULL, OPEN_EXISTING, 0, 0);

	// XML-файл отсутсвует
	if (hFile == INVALID_HANDLE_VALUE)
	{
		return false;
	}
	else
	{
		BY_HANDLE_FILE_INFORMATION bfi = {0};
		if (GetFileInformationByHandle(hFile, &bfi))
			mb_Empty = (bfi.nFileSizeHigh == 0 && bfi.nFileSizeLow == 0);
		CloseHandle(hFile); hFile = NULL;
		if (mb_Empty && bAllowCreate)
		{
			hFile = CreateFile(pszXmlFile, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,
	                   NULL, OPEN_EXISTING, 0, 0);
			if (hFile != INVALID_HANDLE_VALUE)
			{
				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 (mb_Empty && !bAllowCreate)
		return false;

	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;
		}

		hr = mp_File->QueryInterface(IID_IXMLDOMNode, (void **)&pKey);

		if (FAILED(hr))
		{
			_wsprintf(szErr, SKIPLEN(countof(szErr)) L"XML: Root node not found!\nErrCode=0x%08X", (DWORD)hr);
			goto wrap;
		}

		mi_Level = 0;

		while(*regPath)
		{
			// Получить следующий токен
			psz = wcschr(regPath, L'\\');

			if (!psz) psz = regPath + _tcslen(regPath);

			lstrcpyn(szName, regPath, psz-regPath+1);
			// Найти в структуре XML
			pChild = FindItem(pKey, L"key", szName, bAllowCreate);
			pKey->Release();
			pKey = pChild; pChild = NULL;
			mi_Level++;

			if (!pKey)
			{
				if (bAllowCreate)
				{
					_wsprintf(szErr, SKIPLEN(countof(szErr)) L"XML: Can't create key <%s>!", szName);
				}
				else
				{
					//_wsprintf(szErr, SKIPLEN(countof(szErr)) L"XML: key <%s> not found!", szName);
					szErr[0] = 0; // ошибку не показывать - настройки по умолчанию
				}

				goto wrap;
			}

			if (*psz == L'\\')
			{
				regPath = psz + 1;
			}
			else
			{
				break;
			}
		}

		// Нашли, запомнили
		mp_Key = pKey; pKey = NULL;

		if (mp_Key)
		{
			SYSTEMTIME st; wchar_t szTime[32];
			GetLocalTime(&st);
			_wsprintf(szTime, SKIPLEN(countof(szTime)) L"%04i-%02i-%02i %02i:%02i:%02i",
				st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
			SetAttr(mp_Key, L"modified", szTime);
			SetAttr(mp_Key, L"build", gpConEmu->ms_ConEmuBuild);
		}

		lbRc = true;

	} SAFECATCH
	{
		lstrcpy(szErr, L"Exception in SettingsXML::OpenKey");
		lbRc = false;
	}
wrap:

	if (pErr) { pErr->Release(); pErr = NULL; }

	if (pChild) { pChild->Release(); pChild = NULL; }

	if (pKey) { pKey->Release(); pKey = NULL; }

	if (!lbRc && szErr[0] && !abSilent)
	{
		MBoxA(szErr);
	}

	return lbRc;
}