175 lines
5.1 KiB
C++
175 lines
5.1 KiB
C++
/**
|
|
* 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;
|
|
}
|
|
|
|
|