You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
690 lines
22 KiB
690 lines
22 KiB
/******************************************************************************
|
|
|
|
Copyright (c) 1999 Microsoft Corporation
|
|
|
|
Module Name:
|
|
Configuration.cpp
|
|
|
|
Abstract:
|
|
This file contains the implementation of the ...
|
|
|
|
Revision History:
|
|
Davide Massarenti (Dmassare) 01/09/2000
|
|
created
|
|
|
|
******************************************************************************/
|
|
|
|
#include "stdafx.h"
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
const MPC::Config::DefinitionOfTag* MPC::Config::DefinitionOfTag::FindSubTag( /*[in]*/ LPCWSTR szTag ) const
|
|
{
|
|
const DefinitionOfTag** ptr = m_tblSubTags;
|
|
|
|
if(ptr)
|
|
{
|
|
while(*ptr)
|
|
{
|
|
if(!MPC::StrICmp( (*ptr)->m_szTag, szTag ))
|
|
{
|
|
return (*ptr);
|
|
}
|
|
|
|
ptr++;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
const MPC::Config::DefinitionOfAttribute* MPC::Config::DefinitionOfTag::FindAttribute( /*[in]*/ XMLTypes xt, /*[in]*/ LPCWSTR szName ) const
|
|
{
|
|
const DefinitionOfAttribute* ptr = m_tblAttributes;
|
|
|
|
if(ptr)
|
|
{
|
|
while(ptr->m_xt != XT_invalid)
|
|
{
|
|
if(ptr->m_xt == xt)
|
|
{
|
|
if(ptr->m_xt == XT_value || !MPC::StrICmp( ptr->m_szName, szName )) return ptr;
|
|
}
|
|
|
|
ptr++;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
void MPC::Config::ClearValue( /*[in]*/ TypeConstructor* defType ,
|
|
/*[in]*/ const DefinitionOfAttribute* defAttrib )
|
|
{
|
|
{
|
|
void* data = defType->GetOffset( defAttrib->m_offset );
|
|
VARTYPE dest;
|
|
|
|
switch(defAttrib->m_mtType)
|
|
{
|
|
case MT_bool : *(bool *)data = false ; break;
|
|
case MT_BOOL : *(BOOL *)data = FALSE ; break;
|
|
case MT_VARIANT_BOOL: *(VARIANT_BOOL*)data = VARIANT_FALSE; break;
|
|
case MT_int : *(int *)data = 0 ; break;
|
|
case MT_long : *(long *)data = 0 ; break;
|
|
case MT_DWORD : *(DWORD *)data = 0 ; break;
|
|
case MT_float : *(float *)data = 0 ; break;
|
|
case MT_double : *(double *)data = 0 ; break;
|
|
case MT_DATE : *(DATE *)data = 0 ; break;
|
|
case MT_DATE_US : *(DATE *)data = 0 ; break;
|
|
case MT_DATE_CIM : *(DATE *)data = 0 ; break;
|
|
case MT_CHAR : *(CHAR *)data = 0 ; break;
|
|
case MT_WCHAR : *(WCHAR *)data = 0 ; break;
|
|
case MT_BSTR : *(CComBSTR *)data = (LPCWSTR)NULL; break;
|
|
case MT_string : *(MPC::string *)data = "" ; break;
|
|
case MT_wstring : *(MPC::wstring*)data = L"" ; break;
|
|
case MT_bitfield : *(DWORD *)data = 0 ; break;
|
|
}
|
|
}
|
|
|
|
if(defAttrib->m_fPresenceFlag)
|
|
{
|
|
bool* data = (bool*)defType->GetOffset( defAttrib->m_offsetPresence );
|
|
|
|
*data = false;
|
|
}
|
|
}
|
|
|
|
HRESULT MPC::Config::LoadValue( /*[in]*/ TypeConstructor* defType ,
|
|
/*[in]*/ const DefinitionOfAttribute* defAttrib ,
|
|
/*[in/out]*/ CComVariant& value ,
|
|
/*[in]*/ bool fFound )
|
|
{
|
|
__MPC_FUNC_ENTRY( COMMONID, "MPC::Config::LoadValue" );
|
|
|
|
USES_CONVERSION;
|
|
|
|
HRESULT hr;
|
|
|
|
|
|
if(fFound)
|
|
{
|
|
void* data = defType->GetOffset( defAttrib->m_offset );
|
|
VARTYPE dest;
|
|
|
|
|
|
switch(defAttrib->m_mtType)
|
|
{
|
|
case MT_bool : dest = VT_BOOL ; break;
|
|
case MT_BOOL : dest = VT_BOOL ; break;
|
|
case MT_VARIANT_BOOL: dest = VT_BOOL ; break;
|
|
case MT_int : dest = VT_I4 ; break;
|
|
case MT_long : dest = VT_I4 ; break;
|
|
case MT_DWORD : dest = VT_I4 ; break;
|
|
case MT_float : dest = VT_R4 ; break;
|
|
case MT_double : dest = VT_R8 ; break;
|
|
case MT_DATE : dest = VT_ILLEGAL; break;
|
|
case MT_DATE_US : dest = VT_ILLEGAL; break;
|
|
case MT_DATE_CIM : dest = VT_ILLEGAL; break;
|
|
case MT_CHAR : dest = VT_BSTR ; break;
|
|
case MT_WCHAR : dest = VT_BSTR ; break;
|
|
case MT_BSTR : dest = VT_BSTR ; break;
|
|
case MT_string : dest = VT_BSTR ; break;
|
|
case MT_wstring : dest = VT_BSTR ; break;
|
|
case MT_bitfield : dest = VT_BSTR ; break;
|
|
default : __MPC_SET_ERROR_AND_EXIT(hr, E_INVALIDARG);
|
|
}
|
|
|
|
if(dest == VT_ILLEGAL)
|
|
{
|
|
LPCWSTR szDate;
|
|
bool fCIM = false;
|
|
LCID lcid = 0;
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, value.ChangeType( VT_BSTR ));
|
|
szDate = value.bstrVal; SANITIZEWSTR(szDate);
|
|
|
|
switch(defAttrib->m_mtType)
|
|
{
|
|
case MT_DATE : fCIM = false; lcid = 0; break;
|
|
case MT_DATE_US : fCIM = false; lcid = -1; break;
|
|
case MT_DATE_CIM: fCIM = true ; lcid = 0; break;
|
|
}
|
|
|
|
|
|
//
|
|
// We try as much as we can to parse the date. First the expected format, then the US one, finally the user default.
|
|
//
|
|
if(FAILED(MPC::ConvertStringToDate( szDate, *(DATE*)data, /*fGMT*/false, fCIM, lcid )))
|
|
{
|
|
if(FAILED(MPC::ConvertStringToDate( szDate, *(DATE*)data, /*fGMT*/false, /*fCIM*/false, -1 )))
|
|
{
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::ConvertStringToDate( szDate, *(DATE*)data, /*fGMT*/false, /*fCIM*/false, 0 ));
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, value.ChangeType( dest ));
|
|
|
|
switch(defAttrib->m_mtType)
|
|
{
|
|
case MT_bool : *(bool *)data = (value.boolVal == VARIANT_TRUE) ? true : false; break;
|
|
case MT_BOOL : *(BOOL *)data = (value.boolVal == VARIANT_TRUE) ? TRUE : FALSE; break;
|
|
case MT_VARIANT_BOOL: *(VARIANT_BOOL*)data = value.boolVal ; break;
|
|
case MT_int : *(int *)data = value.lVal ; break;
|
|
case MT_long : *(long *)data = value.lVal ; break;
|
|
case MT_DWORD : *(DWORD *)data = value.lVal ; break;
|
|
case MT_float : *(float *)data = value.fltVal ; break;
|
|
case MT_double : *(double *)data = value.dblVal ; break;
|
|
case MT_CHAR : *(CHAR *)data = value.bstrVal ? ( CHAR)value.bstrVal[0] : 0 ; break;
|
|
case MT_WCHAR : *(WCHAR *)data = value.bstrVal ? (WCHAR)value.bstrVal[0] : 0 ; break;
|
|
case MT_BSTR : *(CComBSTR *)data = value.bstrVal ; break;
|
|
case MT_string : *(MPC::string *)data = OLE2A(SAFEBSTR(value.bstrVal)) ; break;
|
|
case MT_wstring : *(MPC::wstring*)data = SAFEBSTR(value.bstrVal) ; break;
|
|
|
|
case MT_bitfield:
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::ConvertStringToBitField( value.bstrVal, *(DWORD*)data, defAttrib->m_Lookup, /*fUseTilde*/false ));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(defAttrib->m_fPresenceFlag)
|
|
{
|
|
bool* data = (bool*)defType->GetOffset( defAttrib->m_offsetPresence );
|
|
|
|
*data = fFound;
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__MPC_FUNC_CLEANUP;
|
|
|
|
__MPC_FUNC_EXIT(hr);
|
|
}
|
|
|
|
HRESULT MPC::Config::SaveValue( /*[in]*/ const TypeConstructor* defType ,
|
|
/*[in]*/ const DefinitionOfAttribute* defAttrib ,
|
|
/*[out]*/ CComVariant& value ,
|
|
/*[out]*/ bool& fFound )
|
|
{
|
|
__MPC_FUNC_ENTRY( COMMONID, "MPC::Config::SaveValue" );
|
|
|
|
HRESULT hr;
|
|
|
|
|
|
if(defAttrib->m_fPresenceFlag)
|
|
{
|
|
bool* data = (bool*)defType->GetOffset( defAttrib->m_offsetPresence );
|
|
|
|
fFound = *data;
|
|
}
|
|
else
|
|
{
|
|
fFound = true;
|
|
}
|
|
|
|
value.Clear();
|
|
|
|
if(fFound)
|
|
{
|
|
const void* data = defType->GetOffset( defAttrib->m_offset );
|
|
VARTYPE src;
|
|
WCHAR rgBuf[2];
|
|
|
|
switch(defAttrib->m_mtType)
|
|
{
|
|
case MT_bool : value.boolVal = *(bool *)data ? VARIANT_TRUE : VARIANT_FALSE; src = VT_BOOL ; break;
|
|
case MT_BOOL : value.boolVal = *(BOOL *)data ? VARIANT_TRUE : VARIANT_FALSE; src = VT_BOOL ; break;
|
|
case MT_VARIANT_BOOL: value.boolVal = *(VARIANT_BOOL*)data ; src = VT_BOOL ; break;
|
|
case MT_int : value.lVal = *(int *)data ; src = VT_I4 ; break;
|
|
case MT_long : value.lVal = *(long *)data ; src = VT_I4 ; break;
|
|
case MT_DWORD : value.lVal = *(DWORD *)data ; src = VT_I4 ; break;
|
|
case MT_float : value.fltVal = *(float *)data ; src = VT_R4 ; break;
|
|
case MT_double : value.dblVal = *(double *)data ; src = VT_R8 ; break;
|
|
case MT_DATE : ; src = VT_ILLEGAL; break;
|
|
case MT_DATE_US : ; src = VT_ILLEGAL; break;
|
|
case MT_DATE_CIM : ; src = VT_ILLEGAL; break;
|
|
case MT_CHAR : rgBuf[0] = *(CHAR *)data; rgBuf[1] = 0; value = rgBuf ; src = VT_BSTR ; break;
|
|
case MT_WCHAR : rgBuf[0] = *(WCHAR *)data; rgBuf[1] = 0; value = rgBuf ; src = VT_BSTR ; break;
|
|
case MT_BSTR : value = *(CComBSTR *)data ; src = VT_BSTR ; break;
|
|
case MT_string : value = ((MPC::string *)data)->c_str() ; src = VT_BSTR ; break;
|
|
case MT_wstring : value = ((MPC::wstring*)data)->c_str() ; src = VT_BSTR ; break;
|
|
|
|
case MT_bitfield:
|
|
{
|
|
MPC::wstring strText;
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::ConvertBitFieldToString( *(DWORD*)data, strText, defAttrib->m_Lookup ));
|
|
|
|
value = strText.c_str(); src = VT_BSTR;
|
|
}
|
|
break;
|
|
|
|
default: __MPC_SET_ERROR_AND_EXIT(hr, E_INVALIDARG);
|
|
}
|
|
|
|
if(src == VT_ILLEGAL)
|
|
{
|
|
MPC::wstring strDate;
|
|
bool fCIM = false;
|
|
LCID lcid = 0;
|
|
|
|
switch(defAttrib->m_mtType)
|
|
{
|
|
case MT_DATE : fCIM = false; lcid = 0; break;
|
|
case MT_DATE_US : fCIM = false; lcid = -1; break;
|
|
case MT_DATE_CIM: fCIM = true ; lcid = 0; break;
|
|
}
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::ConvertDateToString( *(DATE*)data, strDate, /*fGMT*/false, fCIM, lcid ));
|
|
|
|
value = strDate.c_str();
|
|
}
|
|
else if(src != VT_BSTR)
|
|
{
|
|
value.vt = src;
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, value.ChangeType( VT_BSTR ));
|
|
}
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__MPC_FUNC_CLEANUP;
|
|
|
|
__MPC_FUNC_EXIT(hr);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
HRESULT MPC::Config::LoadNode( /*[in]*/ TypeConstructor* defType ,
|
|
/*[in]*/ const DefinitionOfTag* defTag ,
|
|
/*[in]*/ IXMLDOMNode* xdn )
|
|
{
|
|
__MPC_FUNC_ENTRY( COMMONID, "MPC::Config::LoadNode" );
|
|
|
|
HRESULT hr;
|
|
const DefinitionOfTag* defSubTag;
|
|
const DefinitionOfAttribute* defAttrib;
|
|
|
|
|
|
//
|
|
// First of all, clean all the variables.
|
|
//
|
|
defAttrib = defTag->m_tblAttributes;
|
|
if(defAttrib)
|
|
{
|
|
while(defAttrib->m_xt != XT_invalid)
|
|
{
|
|
ClearValue( defType, defAttrib );
|
|
|
|
defAttrib++;
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// Load all the attributes.
|
|
//
|
|
{
|
|
CComPtr<IXMLDOMNamedNodeMap> xdnnmAttribs;
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, xdn->get_attributes( &xdnnmAttribs ));
|
|
if(xdnnmAttribs)
|
|
{
|
|
while(1)
|
|
{
|
|
CComPtr<IXMLDOMNode> xdnNode;
|
|
CComQIPtr<IXMLDOMAttribute> xdaAttrib;
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, xdnnmAttribs->nextNode( &xdnNode ));
|
|
if(xdnNode == NULL) break;
|
|
|
|
if((xdaAttrib = xdnNode))
|
|
{
|
|
CComBSTR bstrName;
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, xdaAttrib->get_name( &bstrName ));
|
|
|
|
defAttrib = defTag->FindAttribute( XT_attribute, SAFEBSTR( bstrName ) );
|
|
if(defAttrib)
|
|
{
|
|
CComVariant value;
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, xdaAttrib->get_value( &value ));
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, LoadValue( defType, defAttrib, value, true ));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Load the node as value.
|
|
//
|
|
defAttrib = defTag->FindAttribute( XT_value, NULL );
|
|
if(defAttrib)
|
|
{
|
|
MPC::XmlUtil xml( xdn );
|
|
CComVariant value;
|
|
bool fFound;
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, xml.GetValue( NULL, value, fFound ));
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, LoadValue( defType, defAttrib, value, fFound ));
|
|
}
|
|
|
|
//
|
|
// Load all subnodes.
|
|
//
|
|
if(defTag->m_tblSubTags)
|
|
{
|
|
CComPtr<IXMLDOMNode> xdnChild;
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, xdn->get_firstChild( &xdnChild ));
|
|
while(xdnChild)
|
|
{
|
|
CComPtr<IXMLDOMNode> xdnSibling;
|
|
CComBSTR bstrName;
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, xdnChild->get_nodeName( &bstrName ));
|
|
|
|
defAttrib = defTag->FindAttribute( XT_element, SAFEBSTR( bstrName ) );
|
|
if(defAttrib)
|
|
{
|
|
MPC::XmlUtil xml( xdnChild );
|
|
CComVariant value;
|
|
bool fFound;
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, xml.GetValue( NULL, value, fFound ));
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, LoadValue( defType, defAttrib, value, fFound ));
|
|
}
|
|
|
|
defSubTag = defTag->FindSubTag( SAFEBSTR( bstrName ) );
|
|
if(defSubTag)
|
|
{
|
|
TypeConstructor* defSubType;
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, defType->CreateInstance( defSubTag, defSubType ));
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, defSubType->LoadNode( xdnChild ));
|
|
}
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, xdnChild->get_nextSibling( &xdnSibling ));
|
|
xdnChild = xdnSibling;
|
|
}
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__MPC_FUNC_CLEANUP;
|
|
|
|
__MPC_FUNC_EXIT(hr);
|
|
}
|
|
|
|
HRESULT MPC::Config::LoadXmlUtil( /*[in]*/ TypeConstructor* defType ,
|
|
/*[in]*/ MPC::XmlUtil& xml )
|
|
{
|
|
__MPC_FUNC_ENTRY( COMMONID, "MPC::Config::LoadXmlUtil" );
|
|
|
|
HRESULT hr;
|
|
CComPtr<IXMLDOMNode> xdnRoot;
|
|
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, xml.GetRoot( &xdnRoot ));
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, defType->LoadNode( xdnRoot ));
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__MPC_FUNC_CLEANUP;
|
|
|
|
__MPC_FUNC_EXIT(hr);
|
|
}
|
|
|
|
HRESULT MPC::Config::LoadStream( /*[in]*/ TypeConstructor* defType ,
|
|
/*[in]*/ IStream* pStream )
|
|
{
|
|
__MPC_FUNC_ENTRY( COMMONID, "MPC::Config::LoadStream" );
|
|
|
|
HRESULT hr;
|
|
MPC::XmlUtil xml;
|
|
bool fFound;
|
|
bool fLoaded;
|
|
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, xml.LoadAsStream( pStream, defType->GetTag(), fLoaded, &fFound ));
|
|
if(fFound)
|
|
{
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, LoadXmlUtil( defType, xml ));
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__MPC_FUNC_CLEANUP;
|
|
|
|
__MPC_FUNC_EXIT(hr);
|
|
}
|
|
|
|
HRESULT MPC::Config::LoadFile( /*[in]*/ TypeConstructor* defType ,
|
|
/*[in]*/ LPCWSTR szFile )
|
|
{
|
|
__MPC_FUNC_ENTRY( COMMONID, "MPC::Config::LoadFile" );
|
|
|
|
HRESULT hr;
|
|
MPC::XmlUtil xml;
|
|
MPC::wstring strFileOrig( szFile ); strFileOrig += L".orig";
|
|
bool fFound;
|
|
bool fLoaded;
|
|
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, xml.Load( szFile, defType->GetTag(), fLoaded, &fFound ));
|
|
if(fFound == false)
|
|
{
|
|
//
|
|
// If fails, try to load "<file>.orig"
|
|
//
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, xml.Load( strFileOrig.c_str(), defType->GetTag(), fLoaded, &fFound ));
|
|
}
|
|
|
|
if(fFound && fLoaded)
|
|
{
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, LoadXmlUtil( defType, xml ));
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__MPC_FUNC_CLEANUP;
|
|
|
|
__MPC_FUNC_EXIT(hr);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
HRESULT MPC::Config::SaveNode( /*[in]*/ const TypeConstructor* defType ,
|
|
/*[in]*/ const DefinitionOfTag* defTag ,
|
|
/*[in]*/ IXMLDOMNode* xdn )
|
|
{
|
|
__MPC_FUNC_ENTRY( COMMONID, "MPC::Config::SaveNode" );
|
|
|
|
HRESULT hr;
|
|
const DefinitionOfAttribute* defAttrib;
|
|
|
|
|
|
defAttrib = defTag->m_tblAttributes;
|
|
if(defAttrib)
|
|
{
|
|
MPC::XmlUtil xml( xdn );
|
|
|
|
while(defAttrib->m_xt != XT_invalid)
|
|
{
|
|
CComVariant value;
|
|
bool fFound;
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, SaveValue( defType, defAttrib, value, fFound ));
|
|
if(fFound)
|
|
{
|
|
if(defAttrib->m_xt == XT_attribute)
|
|
{
|
|
CComPtr<IXMLDOMAttribute> xdaAttrib;
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, xml.PutAttribute( NULL, defAttrib->m_szName, &xdaAttrib, fFound ));
|
|
if(fFound)
|
|
{
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, xdaAttrib->put_value( value ));
|
|
}
|
|
}
|
|
else if(defAttrib->m_xt == XT_value)
|
|
{
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, xml.PutValue( NULL, value, fFound ));
|
|
}
|
|
else if(defAttrib->m_xt == XT_element)
|
|
{
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, xml.PutValue( defAttrib->m_szName, value, fFound ));
|
|
}
|
|
}
|
|
|
|
defAttrib++;
|
|
}
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__MPC_FUNC_CLEANUP;
|
|
|
|
__MPC_FUNC_EXIT(hr);
|
|
}
|
|
|
|
HRESULT MPC::Config::SaveSubNode( /*[in]*/ const TypeConstructor* defType ,
|
|
/*[in]*/ IXMLDOMNode* xdn )
|
|
{
|
|
__MPC_FUNC_ENTRY( COMMONID, "MPC::Config::SaveSubNode" );
|
|
|
|
HRESULT hr;
|
|
CComPtr<IXMLDOMNode> xdnChild;
|
|
MPC::XmlUtil xml( xdn );
|
|
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, xml.CreateNode( defType->GetTag(), &xdnChild ));
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, defType->SaveNode( xdnChild ));
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__MPC_FUNC_CLEANUP;
|
|
|
|
__MPC_FUNC_EXIT(hr);
|
|
}
|
|
|
|
HRESULT MPC::Config::SaveXmlUtil( /*[in ]*/ const TypeConstructor* defType ,
|
|
/*[out]*/ MPC::XmlUtil& xml )
|
|
{
|
|
__MPC_FUNC_ENTRY( COMMONID, "MPC::Config::SaveXmlUtil" );
|
|
|
|
HRESULT hr;
|
|
CComPtr<IXMLDOMNode> xdnRoot;
|
|
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, xml.New( defType->GetTag() ));
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, xml.GetRoot( &xdnRoot ));
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, defType->SaveNode( xdnRoot ));
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__MPC_FUNC_CLEANUP;
|
|
|
|
__MPC_FUNC_EXIT(hr);
|
|
}
|
|
|
|
HRESULT MPC::Config::SaveStream( /*[in]*/ const TypeConstructor* defType ,
|
|
/*[in]*/ IStream* *ppStream )
|
|
{
|
|
__MPC_FUNC_ENTRY( COMMONID, "MPC::Config::SaveStream" );
|
|
|
|
HRESULT hr;
|
|
MPC::XmlUtil xml;
|
|
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, SaveXmlUtil( defType, xml ));
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, xml.SaveAsStream( (IUnknown**)ppStream ));
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__MPC_FUNC_CLEANUP;
|
|
|
|
__MPC_FUNC_EXIT(hr);
|
|
}
|
|
|
|
HRESULT MPC::Config::SaveFile( /*[in]*/ const TypeConstructor* defType ,
|
|
/*[in]*/ LPCWSTR szFile )
|
|
{
|
|
__MPC_FUNC_ENTRY( COMMONID, "MPC::Config::SaveFile" );
|
|
|
|
HRESULT hr;
|
|
MPC::XmlUtil xml;
|
|
MPC::wstring strFileNew ( szFile ); strFileNew += L".new";
|
|
MPC::wstring strFileOrig( szFile ); strFileOrig += L".orig";
|
|
|
|
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, SaveXmlUtil( defType, xml ));
|
|
|
|
|
|
//
|
|
// First of all, delete "<file>.new" and recreate it.
|
|
//
|
|
::SetFileAttributesW( strFileNew.c_str(), FILE_ATTRIBUTE_NORMAL );
|
|
::DeleteFileW ( strFileNew.c_str() );
|
|
__MPC_EXIT_IF_METHOD_FAILS(hr, xml.Save( strFileNew.c_str() ));
|
|
|
|
//
|
|
// Then move "<file>" to "<file>.orig"
|
|
//
|
|
::SetFileAttributesW( szFile , FILE_ATTRIBUTE_NORMAL );
|
|
::SetFileAttributesW( strFileOrig.c_str(), FILE_ATTRIBUTE_NORMAL );
|
|
::DeleteFileW ( strFileOrig.c_str() );
|
|
if(::MoveFileW( szFile, strFileOrig.c_str() ) == FALSE)
|
|
{
|
|
DWORD dwRes = ::GetLastError();
|
|
|
|
if(dwRes != ERROR_FILE_NOT_FOUND)
|
|
{
|
|
__MPC_SET_WIN32_ERROR_AND_EXIT(hr, dwRes);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Then rename "<file>.new" to "<file>"
|
|
//
|
|
__MPC_EXIT_IF_CALL_RETURNS_FALSE(hr, ::MoveFileW( strFileNew.c_str(), szFile ));
|
|
|
|
//
|
|
// Finally delete "<file>.orig"
|
|
//
|
|
(void)::DeleteFileW( strFileOrig.c_str() );
|
|
|
|
|
|
hr = S_OK;
|
|
|
|
|
|
__MPC_FUNC_CLEANUP;
|
|
|
|
__MPC_FUNC_EXIT(hr);
|
|
}
|