1204 lines
24 KiB
C++
1204 lines
24 KiB
C++
|
/*++ 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
|
||
|
// <TsecRoot xmlns="x-schema:file://c:\temp\Sche1111.tmp">
|
||
|
// Original XML file goes here
|
||
|
// </TsecRoot>
|
||
|
// for validating with the schema
|
||
|
//
|
||
|
char gszXMLHeader1[] = "<TsecRoot xmlns=\"x-schema:file://";
|
||
|
char gszXMLHeader2[] = "\">\r\n";
|
||
|
char gszXMLTail[] = "\r\n</TsecRoot>";
|
||
|
|
||
|
//
|
||
|
// 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;
|
||
|
}
|
||
|
|