blob: 74be68932cb74fcdc65fffc2ce11e035b19a2c60 [file] [log] [blame]
/**
* 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 <string.h>
#include <stdlib.h>
#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<LPCWSTR>(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<LPCWSTR>(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;
}