/*++ BUILD Version: 0000 // Increment this if a change has global effects
Copyright (c) 2000-2002 Microsoft Corporation
Module Name:
parser.cpp
Abstract:
Source file module for parsing XML file
Author:
Xiaohai Zhang (xzhang) 22-March-2000
Revision History:
--*/
#include "windows.h"
#include "objbase.h"
#include "msxml.h"
#include "error.h"
#include "parser.h"
#include "resource.h"
#include "tchar.h"
#include "util.h"
const TCHAR CIds::m_szEmptyString[2] = _T("");
void WINAPI FormatString (
LPTSTR szFmt,
LPTSTR szOutput,
DWORD cchOutput,
...
)
{
va_list ap;
va_start (ap, cchOutput);
FormatMessage (
FORMAT_MESSAGE_FROM_STRING,
szFmt,
0,
0,
szOutput,
cchOutput,
&ap
);
va_end (ap);
}
///////////////////////////////////////////////////////////
//
// CXMLParser implementation
//
///////////////////////////////////////////////////////////
//
// With the XML file provided by the user, we create a temporary file
// with the format of
//
// Original XML file goes here
//
// for validating with the schema
//
char gszXMLHeader1[] = "\r\n";
char gszXMLTail[] = "\r\n";
//
// Constructor / Destructor
//
CXMLParser::CXMLParser (void)
{
m_bInited = FALSE;
m_szXMLFile[0] = 0;
m_szTempSchema[0] = 0;
m_szTempXML[0] = 0;
m_pDocInput = NULL;
}
CXMLParser::~CXMLParser ()
{
if (m_pDocInput)
m_pDocInput->Release();
}
//
// Public functions
//
HRESULT CXMLParser::SetXMLFile (LPCTSTR szFile)
{
HRESULT hr = S_OK;
OFSTRUCT ofs;
HANDLE hFile;
if (szFile == NULL ||
_tcslen(szFile) > sizeof(m_szXMLFile)/sizeof(TCHAR) - 1)
{
hr = TSECERR_BADFILENAME;
goto ExitHere;
}
if ((hFile = CreateFile (
szFile,
0,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
)) == INVALID_HANDLE_VALUE)
{
hr = TSECERR_FILENOTEXIST;
goto ExitHere;
}
else
{
CloseHandle (hFile);
}
_tcscpy (m_szXMLFile, szFile);
ExitHere:
return hr;
}
HRESULT CXMLParser::GetXMLFile (LPTSTR szFile, DWORD cch)
{
return E_NOTIMPL;
}
HRESULT CXMLParser::CreateTempFiles ()
{
HRESULT hr = S_OK;
TCHAR szTempPath[MAX_PATH];
char szAnsiFile[MAX_PATH * sizeof(TCHAR)];
HINSTANCE hModule;
HRSRC hRes;
HGLOBAL hSchema;
LPVOID lpSchema;
DWORD dwSchemaSize;
HANDLE hFileSchema = NULL;
DWORD dwBytesWritten;
HANDLE hFileXML = NULL;
HANDLE hFileUserXML = NULL;
DWORD dwBytesRead;
TCHAR szBuf[256];
//
// Prepare temporary file path
//
if (GetTempPath (sizeof(szTempPath)/sizeof(TCHAR), szTempPath) == 0 ||
GetTempFileName (
szTempPath,
TEXT("Schema"),
0,
m_szTempSchema
) == 0 ||
GetTempFileName (
szTempPath,
TEXT("XML"),
0,
m_szTempXML
) == 0
)
{
hr = HRESULT_FROM_WIN32 (GetLastError ());
goto ExitHere;
}
//
// Prepare the temporary file containing the schema
//
// Load the schema.xml resource
hModule = GetModuleHandle (NULL);
if (hModule == NULL)
{
hr = HRESULT_FROM_WIN32 (GetLastError ());
goto ExitHere;
}
hRes = FindResource (
hModule,
MAKEINTRESOURCE(IDR_SCHEMA),
MAKEINTRESOURCE(SCHEMARES)
);
if (hRes == NULL)
{
hr = HRESULT_FROM_WIN32 (GetLastError ());
goto ExitHere;
}
hSchema = LoadResource (
hModule,
hRes);
if (hSchema == NULL)
{
hr = HRESULT_FROM_WIN32 (GetLastError ());
goto ExitHere;
}
lpSchema = LockResource (hSchema);
if (lpSchema == NULL)
{
hr = HRESULT_FROM_WIN32 (GetLastError ());
goto ExitHere;
}
dwSchemaSize = SizeofResource (hModule, hRes);
if (dwSchemaSize == 0)
{
hr = HRESULT_FROM_WIN32 (GetLastError ());
goto ExitHere;
}
// Copy schema.xml into the temporary file
hFileSchema = CreateFile (
m_szTempSchema,
GENERIC_WRITE,
0,
NULL,
OPEN_ALWAYS | TRUNCATE_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (hFileSchema == INVALID_HANDLE_VALUE)
{
hr = HRESULT_FROM_WIN32 (GetLastError ());
goto ExitHere;
}
if (!WriteFile (
hFileSchema,
lpSchema,
dwSchemaSize,
&dwBytesWritten,
NULL
))
{
hr = HRESULT_FROM_WIN32 (GetLastError ());
goto ExitHere;
}
CloseHandle (hFileSchema);
hFileSchema = INVALID_HANDLE_VALUE;
//
// Now create the temp file for the XML file to be parsed
//
hFileXML = CreateFile (
m_szTempXML,
GENERIC_WRITE,
0,
NULL,
OPEN_ALWAYS | TRUNCATE_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (hFileXML == INVALID_HANDLE_VALUE)
{
hr = HRESULT_FROM_WIN32 (GetLastError ());
goto ExitHere;
}
// Write the XML header
if (!WriteFile (
hFileXML,
gszXMLHeader1,
lstrlenA(gszXMLHeader1),
&dwBytesWritten,
NULL
))
{
hr = HRESULT_FROM_WIN32 (GetLastError ());
goto ExitHere;
}
#ifdef UNICODE
if (WideCharToMultiByte (
CP_ACP,
0,
m_szTempSchema,
-1,
szAnsiFile,
sizeof(szAnsiFile),
NULL,
NULL
) == 0)
{
hr = HRESULT_FROM_WIN32 (GetLastError ());
goto ExitHere;
}
#else
lstrcpy (szAnsiFile, m_szTempSchema);
#endif
if (!WriteFile (
hFileXML,
szAnsiFile,
lstrlenA (szAnsiFile),
&dwBytesWritten,
NULL
))
{
hr = HRESULT_FROM_WIN32 (GetLastError ());
goto ExitHere;
}
if (!WriteFile (
hFileXML,
gszXMLHeader2,
lstrlenA(gszXMLHeader2),
&dwBytesWritten,
NULL
))
{
hr = HRESULT_FROM_WIN32 (GetLastError ());
goto ExitHere;
}
// Copy over the input XML file
hFileUserXML = CreateFile (
m_szXMLFile,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (hFileUserXML == INVALID_HANDLE_VALUE)
{
hr = HRESULT_FROM_WIN32 (GetLastError ());
goto ExitHere;
}
while (ReadFile (
hFileUserXML,
szBuf,
sizeof(szBuf),
&dwBytesRead,
NULL) &&
dwBytesRead > 0)
{
if (!WriteFile (
hFileXML,
szBuf,
dwBytesRead,
&dwBytesWritten,
NULL
))
{
hr = HRESULT_FROM_WIN32 (GetLastError ());
goto ExitHere;
}
}
CloseHandle (hFileUserXML);
hFileUserXML = INVALID_HANDLE_VALUE;
// Write the XML tail
if (!WriteFile (
hFileXML,
gszXMLTail,
lstrlenA(gszXMLTail),
&dwBytesWritten,
NULL
))
{
hr = HRESULT_FROM_WIN32 (GetLastError ());
goto ExitHere;
}
CloseHandle (hFileXML);
hFileXML = INVALID_HANDLE_VALUE;
ExitHere:
if (FAILED (hr))
{
m_szTempSchema[0] = 0;
m_szTempXML[0] = 0;
}
if (hFileSchema != INVALID_HANDLE_VALUE)
{
CloseHandle (hFileSchema);
}
if (hFileXML != INVALID_HANDLE_VALUE)
{
CloseHandle (hFileXML);
}
if (hFileUserXML != INVALID_HANDLE_VALUE)
{
CloseHandle (hFileUserXML);
}
return hr;
}
HRESULT CXMLParser::ReportParsingError ()
{
HRESULT hr = S_OK;
IXMLDOMParseError * pError = NULL;
long lErrCode;
long lLineNum;
long lLinePos;
BSTR szReason = NULL;
BSTR szSrc =NULL;
LPTSTR szError = NULL;
TCHAR szBuf[256];
TCHAR szBuf2[256];
HINSTANCE hModule;
CIds IdsError (IDS_ERROR);
// Check to make sure we have a document to work on
if (m_pDocInput == NULL)
{
goto ExitHere;
}
// Make sure we do have an error to report
hr = m_pDocInput->get_parseError (&pError);
if (FAILED (hr))
{
goto ExitHere;
}
hr = pError->get_errorCode (&lErrCode);
if (FAILED (hr) || lErrCode == 0)
{
goto ExitHere;
}
// Collect error information
if (
(hr = pError->get_line (&lLineNum)) != 0 ||
(hr = pError->get_linepos (&lLinePos)) != 0 ||
(hr = pError->get_reason (&szReason)) != 0 ||
(hr = pError->get_srcText (&szSrc)) != 0)
{
goto ExitHere;
}
// adjust line number because we added one line
--lLineNum;
//
// Format error report
//
// The format is similar to the following
//
// Invalid XML file format
//
// Failure reason goes here
//
// Line 2, Pos 12
//
// Failure source goes here
// -----^
//
hModule = GetModuleHandle (NULL);
if (hModule == NULL)
{
hr = HRESULT_FROM_WIN32 (GetLastError ());
goto ExitHere;
}
// Get the text of "Invalid XML file format"
if (FormatMessage (
FORMAT_MESSAGE_FROM_HMODULE,
hModule,
TSEC_INVALFILEFORMAT,
0,
szBuf,
sizeof(szBuf)/sizeof(TCHAR),
NULL
) == 0)
{
hr = HRESULT_FROM_WIN32 (GetLastError ());
goto ExitHere;
}
szError = AppendStringAndFree (szError, szBuf);
// Put in the failure reason
if (szError == NULL ||
((szError = AppendStringAndFree (szError, TEXT("\r\n"))) == NULL) ||
((szError = AppendStringAndFree (szError, szReason)) == NULL) ||
((szError = AppendStringAndFree (szError, TEXT("\r\n"))) == NULL)
)
{
hr = TSECERR_NOMEM;
goto ExitHere;
}
// Get the error position string
if (LoadString (
hModule,
IDS_ERRORPOS,
szBuf,
sizeof(szBuf)/sizeof(TCHAR)
) == 0
)
{
hr = HRESULT_FROM_WIN32 (GetLastError ());
goto ExitHere;
}
FormatString (
szBuf,
szBuf2,
sizeof(szBuf2)/sizeof(TCHAR),
lLineNum,
lLinePos
);
// Put error position text & error source text
if (
((szError = AppendStringAndFree (szError, szBuf2)) == NULL) ||
((szError = AppendStringAndFree (szError, TEXT("\r\n\r\n"))) == NULL) ||
((szError = AppendStringAndFree (szError, szSrc)) == NULL)
)
{
hr = TSECERR_NOMEM;
goto ExitHere;
}
// If the error position is not too large, put ----^ to intuitively point
// to the place error occurred
if (lLinePos < sizeof(szBuf)/sizeof(TCHAR) - 1 && lLinePos > 0)
{
szBuf[lLinePos] = 0;
szBuf[--lLinePos] = TEXT('^');
while (lLinePos > 0)
{
szBuf[--lLinePos] = TEXT('-');
}
if (
((szError = AppendStringAndFree (szError, TEXT("\r\n"))) == NULL) ||
((szError = AppendStringAndFree (szError, szBuf)) == NULL)
)
{
hr = TSECERR_NOMEM;
goto ExitHere;
}
}
//
// Now report the error
//
MessagePrint (szError, IdsError.GetString ());
ExitHere:
if (pError)
{
pError->Release ();
}
SysFreeString (szReason);
SysFreeString (szSrc);
if (szError)
{
delete [] szError;
}
return hr;
}
HRESULT CXMLParser::Parse (void)
{
HRESULT hr = S_OK;
IXMLDOMDocument * pDocInput = NULL;
VARIANT_BOOL bSuccess;
VARIANT varXMLFile;
// Ensure we have an xml file to process
if (*m_szXMLFile == 0)
{
hr = TSECERR_BADFILENAME;
goto ExitHere;
}
hr = CreateTempFiles ();
if (FAILED (hr))
{
goto ExitHere;
}
// Create XMLDOMDocument object
hr = CoCreateInstance (
CLSID_DOMFreeThreadedDocument,
NULL,
CLSCTX_INPROC_SERVER,
IID_IXMLDOMDocument,
(void **)&pDocInput
);
if (FAILED (hr) || pDocInput == NULL)
{
goto ExitHere;
}
// Set the validateOnParse property
hr = pDocInput->put_validateOnParse(VARIANT_TRUE);
if (FAILED (hr))
{
goto ExitHere;
}
// We do a synchronous load for now
hr = pDocInput->put_async (VARIANT_TRUE);
if (FAILED (hr))
{
goto ExitHere;
}
// Parse the document
VariantInit (&varXMLFile);
V_VT(&varXMLFile) = VT_BSTR;
V_BSTR(&varXMLFile) = SysAllocString (m_szTempXML);
hr = pDocInput->load (
varXMLFile,
&bSuccess
);
SysFreeString (V_BSTR(&varXMLFile));
if (FAILED (hr))
{
goto ExitHere;
}
if (bSuccess != VARIANT_TRUE)
{
hr = TSECERR_INVALFILEFORMAT;
}
m_pDocInput = pDocInput;
pDocInput = NULL;
ExitHere:
if (pDocInput != NULL)
{
pDocInput->Release();
}
if (m_szTempSchema[0] != 0)
{
DeleteFile (m_szTempSchema);
}
if (m_szTempXML[0] != 0)
{
DeleteFile (m_szTempXML);
}
return hr;
}
HRESULT CXMLParser::GetFirstUser (CXMLUser ** ppUser)
{
HRESULT hr = S_OK;
IXMLDOMElement * pEleRoot = NULL;
IXMLDOMNode * pFirstNode = NULL;
BSTR bstr = NULL;
*ppUser = NULL;
if (m_pDocInput == NULL)
{
hr = S_FALSE;
goto ExitHere;
}
if (FAILED(hr = m_pDocInput->get_documentElement(&pEleRoot)) ||
pEleRoot == NULL)
{
goto ExitHere;
}
if ((bstr = SysAllocString (L"UserList/User")) == NULL)
{
hr = TSECERR_NOMEM;
goto ExitHere;
}
if (FAILED(hr = pEleRoot->selectSingleNode (bstr, &pFirstNode)) ||
pFirstNode == NULL)
{
goto ExitHere;
}
*ppUser = new CXMLUser (pFirstNode);
if (*ppUser == NULL)
{
hr = TSECERR_NOMEM;
goto ExitHere;
}
else
{
pFirstNode->AddRef();
}
ExitHere:
if (pEleRoot)
{
pEleRoot->Release();
}
if (bstr)
{
SysFreeString (bstr);
}
if (pFirstNode)
{
pFirstNode->Release();
}
return hr;
}
///////////////////////////////////////////////////////////
//
// CXMLUser implementation
//
///////////////////////////////////////////////////////////
HRESULT CXMLUser::GetNextUser (CXMLUser **ppNextUser)
{
HRESULT hr = S_OK;
IXMLDOMNode * pNodeNext = NULL;
*ppNextUser = NULL;
if (m_pUserNode == NULL)
{
hr = S_FALSE;
goto ExitHere;
}
if (FAILED(hr = m_pUserNode->get_nextSibling (&pNodeNext)) ||
pNodeNext == NULL)
{
goto ExitHere;
}
*ppNextUser = new CXMLUser (pNodeNext);
if (*ppNextUser == NULL)
{
hr = TSECERR_NOMEM;
// goto ExitHere;
}
else
{
pNodeNext->AddRef();
}
ExitHere:
if (pNodeNext)
{
pNodeNext->Release();
}
return hr;
}
HRESULT CXMLUser::GetDomainUser (LPTSTR szBuf, DWORD cch)
{
HRESULT hr = S_OK;
IXMLDOMNode * pNodeDU = NULL;
BSTR bstrDU = NULL;
BSTR bstrText = NULL;
szBuf[0] = 0;
if (m_pUserNode == NULL)
{
hr = S_FALSE;
goto ExitHere;
}
bstrDU = SysAllocString (L"DomainUser");
if (bstrDU == NULL)
{
hr = TSECERR_NOMEM;
goto ExitHere;
}
hr = m_pUserNode->selectSingleNode (bstrDU, &pNodeDU);
if (FAILED (hr) || pNodeDU == NULL)
{
goto ExitHere;
}
hr = pNodeDU->get_text (&bstrText);
if (FAILED (hr) || bstrText == NULL)
{
goto ExitHere;
}
_tcsncpy (szBuf, bstrText, cch);
szBuf[cch - 1] = 0;
ExitHere:
if (pNodeDU)
{
pNodeDU->Release();
}
if (bstrDU)
{
SysFreeString (bstrDU);
}
if (bstrText)
{
SysFreeString (bstrText);
}
if (szBuf[0] == 0)
{
hr = S_FALSE;
}
return hr;
}
HRESULT CXMLUser::GetFriendlyName (LPTSTR szBuf, DWORD cch)
{
HRESULT hr = S_OK;
IXMLDOMNode * pNodeFN = NULL;
BSTR bstrFN = NULL;
BSTR bstrText = NULL;
szBuf[0] = 0;
if (m_pUserNode == NULL)
{
hr = S_FALSE;
goto ExitHere;
}
bstrFN = SysAllocString (L"FriendlyName");
if (bstrFN == NULL)
{
hr = TSECERR_NOMEM;
goto ExitHere;
}
hr = m_pUserNode->selectSingleNode (bstrFN, &pNodeFN);
if (FAILED (hr) || pNodeFN == NULL)
{
goto ExitHere;
}
hr = pNodeFN->get_text (&bstrText);
if (FAILED (hr) || bstrText == NULL)
{
goto ExitHere;
}
_tcsncpy (szBuf, bstrText, cch);
szBuf[cch - 1] = 0;
ExitHere:
if (pNodeFN)
{
pNodeFN->Release();
}
if (bstrFN)
{
SysFreeString (bstrFN);
}
if (bstrText)
{
SysFreeString (bstrText);
}
return hr;
}
HRESULT CXMLUser::IsNoMerge (BOOL *pb)
{
HRESULT hr = S_OK;
IXMLDOMNamedNodeMap * pAttribs = NULL;
IXMLDOMNode * pAttrib = NULL;
BSTR bstrNM = NULL;
VARIANT varNM;
if (m_pUserNode == NULL)
{
hr = S_FALSE;
goto ExitHere;
}
hr = m_pUserNode->get_attributes(&pAttribs);
if (FAILED (hr) || pAttribs == NULL)
{
goto ExitHere;
}
bstrNM = SysAllocString (L"NoMerge");
if (bstrNM == NULL)
{
hr = TSECERR_NOMEM;
goto ExitHere;
}
hr = pAttribs->getNamedItem(bstrNM, &pAttrib);
if (FAILED (hr) || pAttrib == NULL)
{
goto ExitHere;
}
VariantInit (&varNM);
hr = pAttrib->get_nodeTypedValue (&varNM);
if (FAILED(hr))
{
VariantClear (&varNM);
goto ExitHere;
}
if (V_VT(&varNM) == VT_BOOL)
{
*pb = (V_BOOL(&varNM) == VARIANT_TRUE) ? TRUE : FALSE;
}
else if (V_VT(&varNM) == VT_BSTR)
{
*pb = (V_BSTR(&varNM)[0] == L'1') ? TRUE : FALSE;
}
else
{
*pb = FALSE;
}
VariantClear (&varNM);
ExitHere:
if (bstrNM)
{
SysFreeString (bstrNM);
}
if (pAttrib)
{
pAttrib->Release();
}
if (pAttribs)
{
pAttribs->Release();
}
return hr;
}
HRESULT CXMLUser::GetFirstLine (CXMLLine ** ppLine)
{
HRESULT hr = S_OK;
BSTR bstrLine = NULL;
IXMLDOMNode * pNodeLine = NULL;
*ppLine = NULL;
if (m_pUserNode == NULL)
{
hr = S_FALSE;
goto ExitHere;
}
bstrLine = SysAllocString (L"LineList/Line");
if (bstrLine == NULL)
{
hr = TSECERR_NOMEM;
goto ExitHere;
}
hr = m_pUserNode->selectSingleNode (bstrLine, &pNodeLine);
if (FAILED(hr) || pNodeLine == NULL)
{
goto ExitHere;
}
*ppLine = new CXMLLine (pNodeLine);
if (*ppLine == NULL)
{
hr = TSECERR_NOMEM;
goto ExitHere;
}
else
{
pNodeLine->AddRef();
}
ExitHere:
if (pNodeLine)
{
pNodeLine->Release();
}
if (bstrLine)
{
SysFreeString (bstrLine);
}
return hr;
}
///////////////////////////////////////////////////////////
//
// CXMLLine implementation
//
///////////////////////////////////////////////////////////
HRESULT CXMLLine::GetNextLine (CXMLLine ** ppLine)
{
HRESULT hr = S_OK;
IXMLDOMNode * pNodeNext = NULL;
*ppLine = NULL;
if (m_pLineNode == NULL)
{
hr = S_FALSE;
goto ExitHere;
}
hr = m_pLineNode->get_nextSibling (&pNodeNext);
if (FAILED(hr) || pNodeNext == NULL)
{
goto ExitHere;
}
*ppLine = new CXMLLine (pNodeNext);
if (*ppLine == NULL)
{
hr = TSECERR_NOMEM;
}
else
{
pNodeNext->AddRef();
}
ExitHere:
if (pNodeNext)
{
pNodeNext->Release();
}
return hr;
}
HRESULT CXMLLine::GetAddress (LPTSTR szBuf, DWORD cch)
{
HRESULT hr = S_OK;
BSTR bstrAddr = NULL;
BSTR bstrText = NULL;
IXMLDOMNode * pNodeAddr = NULL;
if (m_pLineNode == NULL)
{
hr = S_FALSE;
goto ExitHere;
}
bstrAddr = SysAllocString (L"Address");
if (bstrAddr == NULL)
{
hr = TSECERR_NOMEM;
goto ExitHere;
}
hr = m_pLineNode->selectSingleNode (bstrAddr, &pNodeAddr);
if (FAILED(hr) || pNodeAddr == NULL)
{
goto ExitHere;
}
hr = pNodeAddr->get_text(&bstrText);
if (FAILED(hr) || bstrText == NULL)
{
goto ExitHere;
}
_tcsncpy (szBuf, bstrText, cch);
szBuf[cch - 1] = 0;
ExitHere:
if (bstrAddr)
{
SysFreeString (bstrAddr);
}
if (bstrText)
{
SysFreeString (bstrText);
}
if (pNodeAddr)
{
pNodeAddr->Release();
}
return hr;
}
HRESULT CXMLLine::GetPermanentID (ULONG * pID)
{
HRESULT hr = S_OK;
BSTR bstrPID = NULL;
IXMLDOMNode * pNodePID = NULL;
VARIANT varPID;
if (m_pLineNode == NULL)
{
hr = S_FALSE;
goto ExitHere;
}
bstrPID = SysAllocString (L"PermanentID");
if (bstrPID == NULL)
{
hr = TSECERR_NOMEM;
goto ExitHere;
}
hr = m_pLineNode->selectSingleNode (bstrPID, &pNodePID);
if (FAILED(hr) || pNodePID == NULL)
{
goto ExitHere;
}
VariantInit (&varPID);
hr = pNodePID->get_nodeTypedValue(&varPID);
if (FAILED(hr))
{
VariantClear (&varPID);
goto ExitHere;
}
if (V_VT(&varPID) == VT_UI4)
{
*pID = (ULONG) V_UI4(&varPID);
}
else
{
hr = S_FALSE;
*pID = 0;
}
VariantClear (&varPID);
ExitHere:
if (bstrPID)
{
SysFreeString (bstrPID);
}
if (pNodePID)
{
pNodePID->Release();
}
return hr;
}
HRESULT CXMLLine::IsPermanentID (BOOL *pb)
{
HRESULT hr = S_OK;
BSTR bstrPID = NULL;
IXMLDOMNode * pNodePID = NULL;
VARIANT varPID;
if (m_pLineNode == NULL)
{
hr = S_FALSE;
goto ExitHere;
}
bstrPID = SysAllocString (L"PermanentID");
if (bstrPID == NULL)
{
hr = TSECERR_NOMEM;
goto ExitHere;
}
hr = m_pLineNode->selectSingleNode (bstrPID, &pNodePID);
if (FAILED(hr) || pNodePID == NULL)
{
*pb = FALSE;
hr = S_OK;
}
else
{
*pb = TRUE;
}
ExitHere:
if (pNodePID)
{
pNodePID->Release();
}
if (bstrPID)
{
SysFreeString (bstrPID);
}
return hr;
}
HRESULT CXMLLine::IsRemove (BOOL *pb)
{
HRESULT hr = S_OK;
IXMLDOMNamedNodeMap * pAttribs = NULL;
IXMLDOMNode * pAttrib = NULL;
BSTR bstrRM = NULL;
VARIANT varRM;
if (m_pLineNode == NULL)
{
hr = S_FALSE;
goto ExitHere;
}
hr = m_pLineNode->get_attributes(&pAttribs);
if (FAILED (hr) || pAttribs == NULL)
{
goto ExitHere;
}
bstrRM = SysAllocString (L"Remove");
if (bstrRM == NULL)
{
hr = TSECERR_NOMEM;
goto ExitHere;
}
hr = pAttribs->getNamedItem(bstrRM, &pAttrib);
if (FAILED (hr) || pAttrib == NULL)
{
goto ExitHere;
}
VariantInit (&varRM);
hr = pAttrib->get_nodeTypedValue (&varRM);
if (FAILED(hr))
{
VariantClear (&varRM);
goto ExitHere;
}
if (V_VT(&varRM) == VT_BOOL)
{
*pb = (V_BOOL(&varRM) == VARIANT_TRUE) ? TRUE : FALSE;
}
else if(V_VT(&varRM) == VT_BSTR)
{
*pb = (V_BSTR(&varRM)[0] == L'1') ? TRUE : FALSE;
}
else
{
*pb = FALSE;
}
VariantClear (&varRM);
ExitHere:
if (bstrRM)
{
SysFreeString (bstrRM);
}
if (pAttrib)
{
pAttrib->Release();
}
if (pAttribs)
{
pAttribs->Release();
}
return hr;
}