/** * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with this * work for additional information regarding copyright ownership. The ASF * licenses this file to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ #include "winutils.h" #include #include #import "msxml6.dll" exclude("ISequentialStream", "_FILETIME") #define ERROR_CHECK_HRESULT_DONE(hr, message) \ if (FAILED(hr)) { \ dwError = (DWORD) hr; \ LogDebugMessage(L"%s: %x", message, hr); \ goto done; \ } DWORD BuildPathRelativeToModule( __in LPCWSTR relativePath, __in size_t len, __out_ecount(len) LPWSTR buffer) { DWORD dwError = ERROR_SUCCESS; WCHAR moduleFile[MAX_PATH]; WCHAR modulePath[_MAX_DIR]; WCHAR moduleDrive[_MAX_DRIVE]; DWORD size; HRESULT hr = S_OK; errno_t errno; size = GetModuleFileName(NULL, moduleFile, MAX_PATH); dwError = GetLastError(); // Always check due to ERROR_INSUFFICIENT_BUFFER if (dwError) { LogDebugMessage(L"GetModuleFileName: %x\n", dwError); goto done; } errno = _wsplitpath_s(moduleFile, moduleDrive, _MAX_DRIVE, modulePath, _MAX_DIR, NULL, 0, // fname, not interesting NULL, 0); // extenssion, not interesting if (errno) { LogDebugMessage(L"_wsplitpath_s: %x\n", errno); dwError = ERROR_BAD_PATHNAME; goto done; } hr = StringCbPrintf(buffer, len, L"%s%s%s", moduleDrive, modulePath, relativePath); if (FAILED(hr)) { // There is no reliable HRESULT to WIN32 mapping, use code. // see http://blogs.msdn.com/b/oldnewthing/archive/2006/11/03/942851.aspx // dwError = HRESULT_CODE(hr); goto done; } LogDebugMessage(L"BuildPathRelativeToModule: %s (%s)\n", buffer, relativePath); done: return dwError; } DWORD GetConfigValue( __in LPCWSTR relativePath, __in LPCWSTR keyName, __out size_t* len, __out_ecount(len) LPCWSTR* value) { DWORD dwError = ERROR_SUCCESS; WCHAR xmlPath[MAX_PATH]; *len = 0; *value = NULL; dwError = BuildPathRelativeToModule( relativePath, sizeof(xmlPath)/sizeof(WCHAR), xmlPath); if (dwError) { goto done; } dwError = GetConfigValueFromXmlFile(xmlPath, keyName, len, value); done: if (*len) { LogDebugMessage(L"GetConfigValue:%d key:%s len:%d value:%.*s from:%s\n", dwError, keyName, *len, *len, *value, xmlPath); } return dwError; } DWORD GetConfigValueFromXmlFile(__in LPCWSTR xmlFile, __in LPCWSTR keyName, __out size_t* outLen, __out_ecount(len) LPCWSTR* outValue) { DWORD dwError = ERROR_SUCCESS; HRESULT hr; WCHAR keyXsl[8192]; size_t len = 0; LPWSTR value = NULL; BOOL comInitialized = FALSE; *outLen = 0; *outValue = NULL; hr = CoInitialize(NULL); ERROR_CHECK_HRESULT_DONE(hr, L"CoInitialize"); comInitialized = TRUE; hr = StringCbPrintf(keyXsl, sizeof(keyXsl), L"//configuration/property[name='%s']/value/text()", keyName); ERROR_CHECK_HRESULT_DONE(hr, L"StringCbPrintf"); try { MSXML2::IXMLDOMDocument2Ptr pDoc; hr = pDoc.CreateInstance(__uuidof(MSXML2::DOMDocument60), NULL, CLSCTX_INPROC_SERVER); ERROR_CHECK_HRESULT_DONE(hr, L"CreateInstance"); pDoc->async = VARIANT_FALSE; pDoc->validateOnParse = VARIANT_FALSE; pDoc->resolveExternals = VARIANT_FALSE; _variant_t file(xmlFile); if (VARIANT_FALSE == pDoc->load(file)) { dwError = pDoc->parseError->errorCode; LogDebugMessage(L"load %s failed:%d %s\n", xmlFile, dwError, static_cast(pDoc->parseError->Getreason())); goto done; } MSXML2::IXMLDOMElementPtr pRoot = pDoc->documentElement; MSXML2::IXMLDOMNodePtr keyNode = pRoot->selectSingleNode(keyXsl); if (keyNode) { _bstr_t bstrValue = static_cast<_bstr_t>(keyNode->nodeValue); len = bstrValue.length(); value = (LPWSTR) LocalAlloc(LPTR, (len+1) * sizeof(WCHAR)); LPCWSTR lpwszValue = static_cast(bstrValue); memcpy(value, lpwszValue, (len) * sizeof(WCHAR)); LogDebugMessage(L"key:%s :%.*s [%s]\n", keyName, len, value, lpwszValue); *outLen = len; *outValue = value; } else { LogDebugMessage(L"node Xpath:%s not found in:%s\n", keyXsl, xmlFile); } } catch(_com_error errorObject) { dwError = errorObject.Error(); LogDebugMessage(L"catch _com_error:%x %s\n", dwError, errorObject.ErrorMessage()); goto done; } done: if (comInitialized) { CoUninitialize(); } return dwError; }