1689 lines
40 KiB
C++
1689 lines
40 KiB
C++
//++
|
|
//
|
|
// Copyright (c) 1999 Microsoft Corporation
|
|
//
|
|
// Module Name:
|
|
// CXMLParser.c
|
|
//
|
|
// Abstract:
|
|
// This file contains the functions used by System restore in
|
|
// order to real the XML encoded list of protected files. It
|
|
// also performs translations between symbols like %windir% to
|
|
// C:\windows
|
|
//
|
|
// Revision History:
|
|
// Eugene Mesgar (eugenem) 6/16/99
|
|
// created
|
|
// Kanwaljit Marok (kmarok ) 6/06/00
|
|
// rewritten for Whistler
|
|
//--
|
|
|
|
#include <windows.h>
|
|
#include <windowsx.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <tchar.h>
|
|
#include <comdef.h>
|
|
#include <crtdbg.h>
|
|
#include <dbgtrace.h>
|
|
#include <shlobj.h>
|
|
#include <shlwapi.h>
|
|
#include <winreg.h>
|
|
#include <commonlib.h>
|
|
#include "msxml.h"
|
|
#include "xmlparser.h"
|
|
#include "utils.h"
|
|
|
|
|
|
#ifdef THIS_FILE
|
|
#undef THIS_FILE
|
|
#endif
|
|
static char __szTraceSourceFile[] = __FILE__;
|
|
#define THIS_FILE __szTraceSourceFile
|
|
|
|
|
|
//
|
|
// Local Define Section
|
|
//
|
|
|
|
#define MAX_BUF 1024
|
|
#define FILEID 0
|
|
|
|
//
|
|
// SAFERELEASE does a safe release on COM interfaces.
|
|
// Checks to see if not null, if so, calls release
|
|
// method on the interface. Then sets the interface to null.
|
|
//
|
|
|
|
#define SAFERELEASE(p) if (p) {(p)->Release(); p = NULL;} else ;
|
|
|
|
//
|
|
// Default string to be assigned to environment variables if
|
|
// cannot assign real folder
|
|
//
|
|
|
|
#define DEFAULT_UNKNOWN _TEXT("C:\\Unknown_")
|
|
#define ICW_REGKEY _TEXT("App Paths\\ICWCONN1.EXE")
|
|
|
|
//
|
|
// Local Utility functions
|
|
//
|
|
|
|
void FixInconsistantBlackslash(LPTSTR pszDirectory);
|
|
|
|
//
|
|
// The constructor
|
|
// Desc: Zero's all memory
|
|
//
|
|
|
|
CXMLFileListParser::CXMLFileListParser()
|
|
{
|
|
LONG lLoop;
|
|
m_pDoc = NULL;
|
|
|
|
for(lLoop = 0;lLoop < NUM_FILE_TYPES;lLoop++)
|
|
{
|
|
m_pDir[lLoop] = m_pExt[lLoop] = m_pFiles[lLoop] = NULL;
|
|
}
|
|
|
|
m_chDefaultType = _TEXT('i');
|
|
m_clComInitialized = 0;
|
|
}
|
|
|
|
CXMLFileListParser::~CXMLFileListParser()
|
|
{
|
|
LONG lLoop;
|
|
|
|
for(lLoop = 0;lLoop < NUM_FILE_TYPES;lLoop++)
|
|
{
|
|
|
|
SAFERELEASE( m_pDir[lLoop] );
|
|
SAFERELEASE( m_pExt[lLoop] );
|
|
SAFERELEASE( m_pFiles[lLoop] );
|
|
}
|
|
|
|
SAFERELEASE( m_pDoc );
|
|
|
|
//
|
|
// we need to do this in a loop
|
|
// so we don't leek resources with refcounting
|
|
//
|
|
|
|
for( lLoop = 0; lLoop < m_clComInitialized ;lLoop++)
|
|
{
|
|
CoUninitialize( ); // lets kill COM!
|
|
}
|
|
}
|
|
|
|
//
|
|
// Init overloaded
|
|
//
|
|
// Main intialization sequence
|
|
//
|
|
// 1) Initializes The Com Space and Creates an XML document
|
|
// 2) Loads in the specified file into the XML document object
|
|
// 3) Takes the document loads all the collections to populate
|
|
// our sub collections ( each list gets its own heading)
|
|
// 4) Sets up our Search->Replace settings
|
|
//
|
|
|
|
BOOL CXMLFileListParser::Init(LPCTSTR pszFile)
|
|
{
|
|
if(!Init())
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if(!ParseFile(pszFile))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if(!LoadCollections())
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
if( !PopulateReplaceEntries() )
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CXMLFileListParser::Init()
|
|
{
|
|
HRESULT hr;
|
|
LONG clLoop;
|
|
|
|
TraceFunctEnter("Init");
|
|
|
|
//
|
|
// If we are reinitializing, make sure we free up old
|
|
// resources and clean up our internal variables
|
|
//
|
|
|
|
for( clLoop = 0; clLoop < NUM_FILE_TYPES; clLoop++)
|
|
{
|
|
SAFERELEASE( m_pDir[clLoop] );
|
|
SAFERELEASE( m_pExt[clLoop] );
|
|
SAFERELEASE( m_pFiles[clLoop] );
|
|
}
|
|
|
|
memset(m_adwVersion,0,sizeof(DWORD) * 4);
|
|
|
|
//
|
|
// Initialize our COM apartment space
|
|
//
|
|
|
|
hr = CoInitialize(NULL);
|
|
m_clComInitialized++;
|
|
|
|
//
|
|
// S_FALSE means the COM apartment space has been initliazed
|
|
// for this procss already
|
|
//
|
|
|
|
if( (hr != S_OK) && (hr != S_FALSE) )
|
|
{
|
|
ErrorTrace(FILEID,"CoInitialize Failed 0x%x", hr);
|
|
m_clComInitialized--;
|
|
goto cleanup;
|
|
}
|
|
|
|
//
|
|
// Create an instance of our XML document object
|
|
//
|
|
|
|
hr = CoCreateInstance(CLSID_XMLDocument, NULL, CLSCTX_INPROC_SERVER,
|
|
IID_IXMLDocument, (void**)&m_pDoc);
|
|
|
|
if( !m_pDoc || !SUCCEEDED(hr) )
|
|
{
|
|
ErrorTrace(FILEID,"CoCreateInstance Failed 0x%x", GetLastError());
|
|
goto cleanup;
|
|
}
|
|
|
|
TraceFunctLeave();
|
|
return(TRUE);
|
|
|
|
cleanup:
|
|
|
|
SAFERELEASE( m_pDoc );
|
|
|
|
TraceFunctLeave();
|
|
return(FALSE);
|
|
}
|
|
|
|
//
|
|
// Method: LoadCollections()
|
|
//
|
|
// Desc:
|
|
// This method goes through the XML file and finds the
|
|
// <FILES>, <DIRECTORIES>, <EXTENSIONS>, <DEFTYPE>, <VERSION>
|
|
// high level tags and then runs LoadOneCollection() on each of
|
|
// them in order to
|
|
// populate the high level m_pDir, m_pFiles, m_pExt arrays ( which
|
|
// have collections for
|
|
// include, exclude, sfp, etc )..
|
|
//
|
|
|
|
BOOL CXMLFileListParser::LoadCollections()
|
|
{
|
|
IXMLElement *pRoot = NULL, *pTempElement = NULL;
|
|
IXMLElementCollection *pChildren = NULL;
|
|
IDispatch *pDispatch = NULL;
|
|
|
|
|
|
BSTR stTagName;
|
|
HRESULT hr;
|
|
|
|
BSTR stTagValue;
|
|
TCHAR szBuf[MAX_BUFFER];
|
|
|
|
LONG clLoop, lCollectionSize;
|
|
|
|
TraceFunctEnter("CXMLFileListParser::LoadCollections");
|
|
|
|
_ASSERT(m_pDoc);
|
|
|
|
if( ( hr = m_pDoc->get_root( &pRoot) ) != S_OK )
|
|
{
|
|
ErrorTrace(FILEID, "IXMLDocument::GetRoot failed 0x%x",GetLastError());
|
|
goto cleanup;
|
|
}
|
|
|
|
if( ( hr = pRoot->get_tagName( &stTagName ) ) != S_OK )
|
|
{
|
|
ErrorTrace(FILEID, "IXMLElement::get_tagName failed 0x%x", hr );
|
|
goto cleanup;
|
|
}
|
|
|
|
if( ConvertAndFreeBSTR( stTagName, szBuf, MAX_BUFFER ) > MAX_BUFFER )
|
|
{
|
|
ErrorTrace(FILEID, "BSTR too large for buffer", 0);
|
|
goto cleanup;
|
|
}
|
|
|
|
//
|
|
// compare filesLPCT
|
|
//
|
|
|
|
if( _tcsicmp( _TEXT("PCHealthProtect"), szBuf ) )
|
|
{
|
|
ErrorTrace(FILEID, "Malformed XML file",0);
|
|
goto cleanup;
|
|
}
|
|
|
|
if( ( hr = pRoot->get_children( &pChildren ) ) != S_OK )
|
|
{
|
|
ErrorTrace(FILEID,"IXMLElement::get_children failed 0x%x", hr);
|
|
goto cleanup;
|
|
}
|
|
|
|
//
|
|
// we no longer need the root;
|
|
//
|
|
|
|
SAFERELEASE(pRoot);
|
|
|
|
if( (hr = pChildren->get_length(&lCollectionSize) ) != S_OK )
|
|
{
|
|
DebugTrace(FILEID,"Error Finding Length 0x%x", hr );
|
|
goto cleanup;
|
|
}
|
|
|
|
//
|
|
// lets get references to all the sub collections
|
|
//
|
|
|
|
for( clLoop = 0; clLoop < lCollectionSize; clLoop++)
|
|
{
|
|
VARIANT v1, v2;
|
|
|
|
v1.vt = VT_I4;
|
|
v2.vt = VT_EMPTY;
|
|
|
|
v1.lVal = clLoop;
|
|
|
|
//
|
|
// get a item from the collection
|
|
//
|
|
|
|
if( (hr = pChildren->item(v1,v2, &pDispatch) ) != S_OK )
|
|
{
|
|
ErrorTrace(FILEID, "Error pChildren->item 0x%x", hr);
|
|
goto cleanup;
|
|
}
|
|
|
|
if( ( hr = pDispatch->QueryInterface(IID_IXMLElement,
|
|
(void **) &pTempElement) ) != S_OK )
|
|
{
|
|
ErrorTrace(FILEID, "Error IDispatch::QueryInterface 0x%d", hr);
|
|
goto cleanup;
|
|
}
|
|
|
|
//
|
|
// lets see which collection it is
|
|
//
|
|
|
|
if( (hr = pTempElement->get_tagName( &stTagName ) ) != S_OK )
|
|
{
|
|
DebugTrace(FILEID, "Error in get_tagName 0x%x", hr );
|
|
goto cleanup;
|
|
}
|
|
|
|
if( ConvertAndFreeBSTR( stTagName, szBuf, MAX_BUFFER ) > MAX_BUFFER )
|
|
{
|
|
ErrorTrace(FILEID, "BSTR too large for buffer", 0);
|
|
goto cleanup;
|
|
}
|
|
|
|
if( !_tcsicmp( _TEXT("DIRECTORIES"), szBuf ) )
|
|
{
|
|
if( !LoadOneCollection(pTempElement, m_pDir ) )
|
|
{
|
|
ErrorTrace(FILEID,"Error Loading Collection",0);
|
|
goto cleanup;
|
|
}
|
|
}
|
|
else if( !_tcsicmp( _TEXT( "FILES"), szBuf ) )
|
|
{
|
|
if( !LoadOneCollection(pTempElement, m_pFiles ) )
|
|
{
|
|
ErrorTrace(FILEID,"Error Loading Collection",0);
|
|
goto cleanup;
|
|
}
|
|
}
|
|
else if( !_tcsicmp( _TEXT( "EXTENSIONS"), szBuf ) )
|
|
{
|
|
if( !LoadOneCollection(pTempElement, m_pExt ) )
|
|
{
|
|
ErrorTrace(FILEID,"Error Loading Collection",0);
|
|
goto cleanup;
|
|
}
|
|
}
|
|
else if( !_tcsicmp( _TEXT( "VERSION"), szBuf ) )
|
|
{
|
|
if( ParseVersion(pTempElement) == FALSE )
|
|
{
|
|
goto cleanup;
|
|
}
|
|
}
|
|
else if( !_tcsicmp( _TEXT( "DEFTYPE"), szBuf ) )
|
|
{
|
|
if( ( hr = pTempElement->get_text( &stTagValue ) ) != S_OK )
|
|
{
|
|
ErrorTrace(FILEID, "Error in IXMLElement::get_text 0x%x", hr);
|
|
goto cleanup;
|
|
}
|
|
|
|
if( ConvertAndFreeBSTR( stTagValue,
|
|
szBuf,
|
|
MAX_BUFFER ) > MAX_BUFFER )
|
|
{
|
|
ErrorTrace(FILEID, "Less space in BSTR to string buffer", 0);
|
|
goto cleanup;
|
|
}
|
|
|
|
//
|
|
// make sure trail, leaing spaces don't get us messed up;
|
|
//
|
|
|
|
TrimString(szBuf);
|
|
|
|
//
|
|
// empty string?
|
|
//
|
|
|
|
if( szBuf[0] == 0 )
|
|
{
|
|
ErrorTrace(FILEID, "Empty string passed to default type.",0);
|
|
goto cleanup;
|
|
}
|
|
|
|
m_chDefaultType = szBuf[0];
|
|
}
|
|
else
|
|
{
|
|
ErrorTrace(FILEID, "Undefiend XML tag in file.",0);
|
|
goto cleanup;
|
|
}
|
|
|
|
SAFERELEASE( pTempElement);
|
|
SAFERELEASE( pDispatch );
|
|
}
|
|
|
|
SAFERELEASE( pChildren );
|
|
|
|
TraceFunctLeave();
|
|
return TRUE;
|
|
|
|
cleanup:
|
|
|
|
SAFERELEASE( pTempElement );
|
|
SAFERELEASE( pDispatch );
|
|
SAFERELEASE( pRoot );
|
|
SAFERELEASE( pChildren );
|
|
|
|
TraceFunctLeave();
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Method: LoadOneCollection(IXMLElement *, IXMLElementCollection **)
|
|
//
|
|
// Desc: Takes a high level node (like <FILES>) and then gets all
|
|
// the sub include,exclude,sfp collections and sets them up in the
|
|
// pCol array (usually passed a member variable like m_pDir, m_pFiles,
|
|
// etc).
|
|
//
|
|
|
|
BOOL CXMLFileListParser::LoadOneCollection(
|
|
IXMLElement *pColHead,
|
|
IXMLElementCollection **pCol )
|
|
{
|
|
|
|
HRESULT hr;
|
|
|
|
IXMLElementCollection *pChildren = NULL;
|
|
IXMLElement *pTempElement = NULL;
|
|
IDispatch *pDispatch = NULL;
|
|
LONG lCollectionSize, clLoop;
|
|
|
|
BSTR stTagName;
|
|
TCHAR szBuf[MAX_BUFFER];
|
|
|
|
_ASSERT( pColHead );
|
|
|
|
TraceFunctEnter("CXMLFileListParser::LoadOneCollection");
|
|
|
|
//
|
|
// Lets make sure we don't have a section called <FILES></FILES>
|
|
//
|
|
|
|
if( (hr = pColHead->get_children( &pChildren )) != S_OK )
|
|
{
|
|
ErrorTrace(FILEID,"Empty <FILES,EXT,DIRECTORY,etc section",0);
|
|
TraceFunctLeave();
|
|
return(TRUE);
|
|
}
|
|
|
|
if( (hr = pChildren->get_length( &lCollectionSize ) ) != S_OK )
|
|
{
|
|
DebugTrace(FILEID, "Error getting collection size. 0x%x", hr );
|
|
goto cleanup;
|
|
}
|
|
|
|
for( clLoop = 0; clLoop < lCollectionSize; clLoop++)
|
|
{
|
|
//
|
|
// Set up OLE style variant varaibles to loop through all the entires
|
|
//
|
|
|
|
VARIANT v1, v2;
|
|
|
|
v1.vt = VT_I4;
|
|
v2.vt = VT_EMPTY;
|
|
|
|
v1.lVal = clLoop;
|
|
|
|
//
|
|
// get a item from the collection
|
|
//
|
|
|
|
if( (hr = pChildren->item(v1,v2, &pDispatch) ) != S_OK )
|
|
{
|
|
ErrorTrace(FILEID, "Error pChildren->item 0x%x", hr);
|
|
goto cleanup;
|
|
}
|
|
|
|
if( ( hr = pDispatch->QueryInterface(IID_IXMLElement,
|
|
(void **) &pTempElement) ) != S_OK )
|
|
{
|
|
ErrorTrace(FILEID, "Error IDispatch::QueryInterface 0x%d", hr);
|
|
goto cleanup;
|
|
}
|
|
|
|
SAFERELEASE( pDispatch );
|
|
|
|
//
|
|
// lets see which collection it is
|
|
//
|
|
if( (hr = pTempElement->get_tagName( &stTagName ) ) != S_OK )
|
|
{
|
|
ErrorTrace(FILEID, "Error in get_tagName 0x%x", hr);
|
|
goto cleanup;
|
|
}
|
|
|
|
if( ConvertAndFreeBSTR( stTagName, szBuf, MAX_BUFFER) > MAX_BUFFER )
|
|
{
|
|
ErrorTrace(FILEID, "Not enough space to convert BString.",0);
|
|
goto cleanup;
|
|
}
|
|
|
|
if( !_tcsicmp( _TEXT("INCLUDE"), szBuf ) )
|
|
{
|
|
if( (hr = pTempElement->get_children( & pCol[INCLUDE_COLL] ) )
|
|
!= S_OK )
|
|
{
|
|
DebugTrace(FILEID,"Error in IXMLElement::get_children 0x%x",hr);
|
|
goto cleanup;
|
|
}
|
|
}
|
|
else if( !_tcsicmp( _TEXT( "EXCLUDE"), szBuf ) )
|
|
{
|
|
if( (hr = pTempElement->get_children( & pCol[EXCLUDE_COLL] ) )
|
|
!= S_OK )
|
|
{
|
|
DebugTrace(FILEID,"Error in IXMLElement::get_children 0x%x",hr);
|
|
goto cleanup;
|
|
}
|
|
}
|
|
else if( !_tcsicmp( _TEXT( "SNAPSHOT"), szBuf ) )
|
|
{
|
|
if( (hr = pTempElement->get_children( & pCol[SNAPSHOT_COLL] ) )
|
|
!= S_OK )
|
|
{
|
|
DebugTrace(FILEID,"Error in IXMLElement::get_children 0x%x",hr);
|
|
goto cleanup;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ErrorTrace(FILEID, "Undefiend XML tag in file.",0);
|
|
goto cleanup;
|
|
}
|
|
|
|
SAFERELEASE( pTempElement);
|
|
}
|
|
|
|
SAFERELEASE( pChildren );
|
|
|
|
TraceFunctLeave();
|
|
return TRUE;
|
|
|
|
cleanup:
|
|
|
|
SAFERELEASE( pTempElement );
|
|
SAFERELEASE( pDispatch );
|
|
SAFERELEASE( pChildren );
|
|
|
|
TraceFunctLeave();
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Function: ParseFile(LPCTSR pszFile)
|
|
// Desc: Loads a file into the member variable m_pDoc.
|
|
//
|
|
|
|
BOOL CXMLFileListParser::ParseFile(LPCTSTR pszFile)
|
|
{
|
|
BSTR pBURL=NULL;
|
|
_bstr_t FileBuffer( pszFile );
|
|
HRESULT hr;
|
|
|
|
TraceFunctEnter("ParseFile");
|
|
|
|
pBURL = FileBuffer.copy();
|
|
|
|
if( !pBURL )
|
|
{
|
|
ErrorTrace(FILEID, "Error allocating space for a BSTR", 0);
|
|
goto cleanup;
|
|
}
|
|
|
|
if( (hr = m_pDoc->put_URL( pBURL ) ) != S_OK )
|
|
{
|
|
DebugTrace(FILEID, "Error m_pDoc->putUrl %0x%x", hr );
|
|
goto cleanup;
|
|
}
|
|
|
|
if( pBURL )
|
|
{
|
|
SysFreeString( pBURL );
|
|
}
|
|
|
|
TraceFunctLeave();
|
|
return(TRUE);
|
|
|
|
cleanup:
|
|
|
|
if( pBURL )
|
|
{
|
|
SysFreeString( pBURL );
|
|
}
|
|
|
|
TraceFunctLeave();
|
|
return(FALSE);
|
|
}
|
|
|
|
//
|
|
// Function: ParseVersion(IXMLElement *pVerElement)
|
|
//
|
|
//
|
|
// Desc: This funciton is called from LoadCollections() when it hits the element
|
|
// containing the XML files version. It takes an IXMLElement
|
|
// object and extracts the version into the m_adwVersion array
|
|
//
|
|
//
|
|
|
|
BOOL CXMLFileListParser::ParseVersion(IXMLElement *pVerElement)
|
|
{
|
|
HRESULT hr;
|
|
BSTR stTagValue;
|
|
TCHAR szTagValue[MAX_BUFFER];
|
|
TCHAR szBuf[256];
|
|
LONG clElement;
|
|
|
|
TraceFunctEnter("CXMLFileListParser::ParseVersionElement");
|
|
|
|
if( (hr = pVerElement->get_text( & stTagValue ) ) != S_OK )
|
|
{
|
|
DebugTrace(FILEID, "Error in IXMLElement::get_text 0x%x", hr );
|
|
goto cleanup;
|
|
}
|
|
|
|
if( ConvertAndFreeBSTR( stTagValue, szTagValue, MAX_BUFFER ) > MAX_BUFFER )
|
|
{
|
|
ErrorTrace(FILEID, "Error conveting the Bstring. Not enough buffer.",0);
|
|
goto cleanup;
|
|
}
|
|
|
|
for( clElement = 0; clElement < 4; clElement++ )
|
|
{
|
|
if( GetField(szTagValue,szBuf,clElement,_TEXT('.') ) == 0 )
|
|
break;
|
|
|
|
m_adwVersion[clElement] = _ttoi( szBuf );
|
|
}
|
|
|
|
TraceFunctLeave();
|
|
return(TRUE);
|
|
|
|
cleanup:
|
|
|
|
TraceFunctLeave();
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// XML Tree traversal and general accessor functions
|
|
// Exposed Wrappers: GetDirectory, GetFile, GetExt
|
|
// GetDirectoryCount, GetFileCount, GetExtCount
|
|
//
|
|
|
|
//
|
|
// RETURN VALUES FOR THE GET FUNCTIONS:
|
|
// lBufMax -- filename was copied OK
|
|
// 0 -- serious error occoured
|
|
// > lBufMax -- the number of TCHARs you really need
|
|
//
|
|
|
|
//
|
|
// BOOL *pfDisable is for the special
|
|
// "protected directory" feature in the VxD.
|
|
//
|
|
|
|
LONG
|
|
CXMLFileListParser::GetDirectory(
|
|
LONG ilElement,
|
|
LPTSTR pszBuf,
|
|
LONG lBufMax,
|
|
TCHAR chType,
|
|
BOOL *pfDisable)
|
|
{
|
|
LONG lReturnValue=0;
|
|
LONG lType;
|
|
|
|
TraceFunctEnter("CXMLFileListParser::GetDirectory");
|
|
|
|
//
|
|
// get the array index of this file type
|
|
//
|
|
|
|
lType = TranslateType( chType );
|
|
|
|
if( !m_pDoc || !m_pDir[lType] )
|
|
{
|
|
TraceFunctLeave();
|
|
return 0;
|
|
}
|
|
|
|
if( (lReturnValue = GetFileInfo(
|
|
m_pDir[lType],
|
|
ilElement,
|
|
pszBuf,
|
|
lBufMax,
|
|
pfDisable)) != lBufMax)
|
|
{
|
|
goto cleanup;
|
|
}
|
|
|
|
if( (lReturnValue = SearchAndReplace(pszBuf, lBufMax) ) != lBufMax )
|
|
{
|
|
goto cleanup;
|
|
}
|
|
|
|
CharUpper( pszBuf );
|
|
|
|
//
|
|
// make sure there are no (lead/trail spaces/tabs)
|
|
//
|
|
|
|
TrimString( pszBuf );
|
|
|
|
cleanup:
|
|
|
|
TraceFunctLeave();
|
|
return( lReturnValue );
|
|
}
|
|
|
|
LONG
|
|
CXMLFileListParser::GetDirectory(
|
|
LONG ilElement,
|
|
LPTSTR pszBuf,
|
|
LONG lBufMax,
|
|
TCHAR chType)
|
|
{
|
|
return( GetDirectory( ilElement, pszBuf, lBufMax, chType, NULL ) );
|
|
}
|
|
|
|
LONG
|
|
CXMLFileListParser::GetExt(
|
|
LONG ilElement,
|
|
LPTSTR pszBuf,
|
|
LONG lBufMax,
|
|
TCHAR chType)
|
|
{
|
|
LONG lReturnValue=0;
|
|
LONG lType;
|
|
|
|
TraceFunctEnter("CXMLFileListParser::GetExt");
|
|
|
|
lType = TranslateType( chType );
|
|
|
|
if( !m_pDoc || !m_pExt[lType] )
|
|
{
|
|
TraceFunctLeave();
|
|
return 0;
|
|
}
|
|
|
|
if( (lReturnValue = GetFileInfo(m_pExt[lType],
|
|
ilElement,
|
|
pszBuf,
|
|
lBufMax,
|
|
NULL)) != lBufMax)
|
|
{
|
|
goto cleanup;
|
|
}
|
|
|
|
if( (lReturnValue = SearchAndReplace(pszBuf, lBufMax) ) != lBufMax )
|
|
{
|
|
goto cleanup;
|
|
}
|
|
|
|
CharUpper( pszBuf );
|
|
|
|
//
|
|
// make sure there are no (lead/trail spaces/tabs)
|
|
//
|
|
|
|
TrimString( pszBuf );
|
|
|
|
cleanup:
|
|
|
|
TraceFunctLeave();
|
|
return( lReturnValue );
|
|
}
|
|
|
|
LONG
|
|
CXMLFileListParser::GetFile(
|
|
LONG ilElement,
|
|
LPTSTR pszBuf,
|
|
LONG lBufMax,
|
|
TCHAR chType)
|
|
{
|
|
LONG lReturnValue=0;
|
|
LONG lType;
|
|
|
|
TraceFunctEnter("CXMLFileListParser::GetFile");
|
|
|
|
lType = TranslateType( chType );
|
|
|
|
if( !m_pDoc || !m_pFiles[lType] )
|
|
{
|
|
TraceFunctLeave();
|
|
return 0;
|
|
}
|
|
|
|
if( (lReturnValue = GetFileInfo(m_pFiles[lType],
|
|
ilElement,
|
|
pszBuf,
|
|
lBufMax,
|
|
NULL)) != lBufMax)
|
|
{
|
|
goto cleanup;
|
|
}
|
|
|
|
if( (lReturnValue = SearchAndReplace(pszBuf, lBufMax) ) != lBufMax )
|
|
{
|
|
goto cleanup;
|
|
}
|
|
|
|
CharUpper( pszBuf );
|
|
|
|
//
|
|
// make sure there are no (lead/trail spaces/tabs)
|
|
//
|
|
|
|
TrimString( pszBuf );
|
|
|
|
cleanup:
|
|
|
|
TraceFunctLeave();
|
|
return( lReturnValue );
|
|
}
|
|
|
|
//
|
|
// GetDirectory/File/ExtCount functions.
|
|
// These functions give you the number of entries in a specific collection.
|
|
// For example: GetFileCount(SNAPSHOT_TYPE) will return the numbert
|
|
// of entries in the FILES main heading, which are under the SNAPSHOT
|
|
// subheading in the XML file.
|
|
//
|
|
|
|
LONG
|
|
CXMLFileListParser::GetDirectoryCount(
|
|
TCHAR chType)
|
|
{
|
|
LONG lReturnValue;
|
|
|
|
TraceFunctEnter("CXMLFileListParser::GetDirectoryCount");
|
|
|
|
lReturnValue = GetCollectionSize( m_pDir[TranslateType(chType)] );
|
|
|
|
TraceFunctLeave();
|
|
return( lReturnValue );
|
|
}
|
|
|
|
LONG
|
|
CXMLFileListParser::GetExtCount(
|
|
TCHAR chType)
|
|
{
|
|
LONG lReturnValue;
|
|
|
|
TraceFunctEnter("CXMLFileListParser::GetExtCount");
|
|
|
|
lReturnValue = GetCollectionSize( m_pExt[TranslateType(chType)] );
|
|
|
|
TraceFunctLeave();
|
|
return( lReturnValue );
|
|
}
|
|
|
|
|
|
LONG
|
|
CXMLFileListParser::GetFileCount(
|
|
TCHAR chType)
|
|
{
|
|
LONG lReturnValue;
|
|
|
|
TraceFunctEnter("CXMLFileListParser::GetFileCount");
|
|
|
|
lReturnValue = GetCollectionSize( m_pFiles[TranslateType(chType)] );
|
|
|
|
TraceFunctLeave();
|
|
return( lReturnValue );
|
|
}
|
|
|
|
//
|
|
// Main internal functions used to get by the wrappers.
|
|
//
|
|
// GetCollectionSize, GetFileInfo
|
|
//
|
|
//
|
|
|
|
LONG
|
|
CXMLFileListParser::GetCollectionSize(
|
|
IXMLElementCollection *pCol)
|
|
{
|
|
LONG lCollectionSize;
|
|
HRESULT hr;
|
|
|
|
TraceFunctEnter("CXMLFileListParser::GetCollectionSize");
|
|
|
|
if( pCol == NULL ) {
|
|
TraceFunctLeave();
|
|
return 0;
|
|
}
|
|
|
|
if( (hr = pCol->get_length(&lCollectionSize) ) != S_OK )
|
|
{
|
|
DebugTrace(FILEID, "Error Finding Length 0x%x", hr );
|
|
goto cleanup;
|
|
}
|
|
|
|
TraceFunctLeave();
|
|
return(lCollectionSize);
|
|
|
|
cleanup:
|
|
|
|
TraceFunctLeave();
|
|
return 0;
|
|
}
|
|
|
|
//
|
|
// RETURN VALUES:
|
|
// lBufMax -- filename was copied OK
|
|
// 0 -- serious error occoured
|
|
// > lBufMax -- the number in TCHAR's that you need.
|
|
//
|
|
|
|
LONG
|
|
CXMLFileListParser::GetFileInfo(
|
|
IXMLElementCollection *pCol,
|
|
LONG ilElement,
|
|
LPTSTR pszBuf,
|
|
LONG lBufMax,
|
|
BOOL *pfDisable)
|
|
{
|
|
|
|
HRESULT hr;
|
|
LONG lLen, lCollectionSize=0, clLoop, lReturnValue=0;
|
|
VARIANT v1, v2;
|
|
|
|
// OLE/COM BSTR variables and helper classes
|
|
|
|
BSTR stTagValue;
|
|
TCHAR szValueBuffer[MAX_BUFFER];
|
|
|
|
// COM interfaces
|
|
IDispatch *pDispatch = NULL;
|
|
IXMLElement *pTempElement = NULL;
|
|
IXMLElementCollection *pChildren = NULL;
|
|
|
|
TraceFunctEnter("CXMLFileListParser::GetFileInfo");
|
|
|
|
//
|
|
// Basic assumptions of the code.
|
|
//
|
|
|
|
_ASSERT(pCol);
|
|
_ASSERT(pszBuf || !lBufMax);
|
|
_ASSERT(pchType);
|
|
|
|
//
|
|
// Set up to make sure protection code is clean
|
|
// Test to see if we have an in-range request.
|
|
//
|
|
|
|
if( (hr = pCol->get_length(&lCollectionSize) ) != S_OK )
|
|
{
|
|
DebugTrace(FILEID, "Error Finding Length 0x%x", hr );
|
|
goto cleanup;
|
|
}
|
|
|
|
if( ilElement >= lCollectionSize )
|
|
{
|
|
ErrorTrace(FILEID,
|
|
"CXMLFileListParser::GetFileInfo (Element out of range)",
|
|
0);
|
|
|
|
goto cleanup;
|
|
}
|
|
|
|
v1.vt = VT_I4;
|
|
v1.lVal = ilElement;
|
|
v2.vt = VT_EMPTY;
|
|
|
|
//
|
|
// get a item from the collection
|
|
//
|
|
|
|
if( (hr = pCol->item(v1,v2, &pDispatch) ) != S_OK )
|
|
{
|
|
ErrorTrace(FILEID, "Error pChildren->item 0x%x", hr);
|
|
goto cleanup;
|
|
}
|
|
|
|
if( ( hr = pDispatch->QueryInterface(IID_IXMLElement,
|
|
(void **) &pTempElement) ) != S_OK )
|
|
{
|
|
ErrorTrace(FILEID, "Error IDispatch::QueryInterface 0x%d", hr);
|
|
goto cleanup;
|
|
}
|
|
|
|
SAFERELEASE( pDispatch );
|
|
|
|
if( (hr = pTempElement->get_text( & stTagValue ) ) != S_OK )
|
|
{
|
|
DebugTrace(FILEID, "Error in IXMLElement::get_text 0x%x", hr );
|
|
goto cleanup;
|
|
}
|
|
|
|
if( ( lLen = ConvertAndFreeBSTR( stTagValue, szValueBuffer, MAX_BUFFER ) ) >
|
|
MAX_BUFFER )
|
|
{
|
|
lReturnValue = lLen + 1;
|
|
goto cleanup;
|
|
}
|
|
|
|
_tcscpy( pszBuf, szValueBuffer );
|
|
|
|
if( pfDisable )
|
|
{
|
|
_bstr_t AttrName( _TEXT("DISABLE") );
|
|
VARIANT AttrValue;
|
|
|
|
*pfDisable = FALSE;
|
|
|
|
//
|
|
// clear the variant
|
|
//
|
|
|
|
VariantInit( &AttrValue );
|
|
|
|
hr = pTempElement->getAttribute( AttrName, &AttrValue );
|
|
|
|
//
|
|
// who cares what the property name is
|
|
//
|
|
|
|
if( hr == S_OK )
|
|
{
|
|
*pfDisable = TRUE;
|
|
VariantClear( &AttrValue );
|
|
}
|
|
}
|
|
|
|
SAFERELEASE( pTempElement );
|
|
|
|
lReturnValue = lBufMax;
|
|
|
|
TraceFunctLeave();
|
|
return(lReturnValue);
|
|
|
|
cleanup:
|
|
|
|
SAFERELEASE( pTempElement );
|
|
SAFERELEASE( pDispatch );
|
|
|
|
// what about BSTR's?
|
|
|
|
TraceFunctLeave();
|
|
return(lReturnValue);
|
|
}
|
|
|
|
BOOL
|
|
CXMLFileListParser::GetVersion(
|
|
LPDWORD pdwVersion)
|
|
{
|
|
|
|
TraceFunctEnter("CXMLFileListParser::GetVersion");
|
|
|
|
_ASSERT( pdwVersion );
|
|
|
|
memcpy( pdwVersion, m_adwVersion, sizeof(DWORD) * 4 );
|
|
|
|
TraceFunctLeave();
|
|
return(TRUE);
|
|
}
|
|
|
|
TCHAR
|
|
CXMLFileListParser::GetDefaultType()
|
|
{
|
|
return( (TCHAR) CharUpper( (LPTSTR) m_chDefaultType) );
|
|
}
|
|
|
|
LONG
|
|
CXMLFileListParser::SearchAndReplace(
|
|
LPTSTR szBuf,
|
|
LONG lMaxBuf)
|
|
{
|
|
TCHAR szTempBuf[MAX_BUFFER];
|
|
DWORD dwResult;
|
|
LONG lReturn = 0;
|
|
|
|
TraceFunctEnter("CXMLFileListParser::SearchAndReplace");
|
|
|
|
dwResult = ExpandEnvironmentStrings( szBuf, szTempBuf, lMaxBuf);
|
|
|
|
if( 0 == dwResult )
|
|
{
|
|
DWORD dwError;
|
|
dwError = GetLastError();
|
|
ErrorTrace(FILEID, "Error in search and replace ec-%d", dwError);
|
|
lReturn = 0;
|
|
goto cleanup;
|
|
}
|
|
|
|
if( dwResult > (lMaxBuf*sizeof(TCHAR) ) )
|
|
{
|
|
ErrorTrace(FILEID, "Buffer too small in Search and replace.",0);
|
|
lReturn = dwResult;
|
|
goto cleanup;
|
|
}
|
|
|
|
_tcscpy( szBuf, szTempBuf );
|
|
lReturn = lMaxBuf;
|
|
|
|
cleanup:
|
|
TraceFunctLeave();
|
|
return lReturn;
|
|
}
|
|
|
|
BOOL
|
|
CXMLFileListParser::DepopulateReplaceEntries()
|
|
{
|
|
LONG clLoop;
|
|
|
|
TraceFunctEnter("CXMLFileListParser::DepopulateReplaceEntries");
|
|
|
|
// This code shouldn't do anything anymore in the new system
|
|
|
|
TraceFunctLeave();
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
GetDSRoot( TCHAR ** pszStr )
|
|
{
|
|
static WCHAR str[MAX_PATH];
|
|
|
|
*pszStr = str;
|
|
|
|
*str = 0;
|
|
|
|
#ifdef UNICODE
|
|
_stprintf( *pszStr, _TEXT("*:\\_restore.%s"), GetMachineGuid());
|
|
#else
|
|
_stprintf( *pszStr, _TEXT("*:\\_restore") );
|
|
#endif
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
GetArchiveDir( TCHAR ** pszStr )
|
|
{
|
|
static TCHAR str[MAX_PATH];
|
|
#if 0
|
|
*pszStr = str;
|
|
_tcscpy( *pszStr, _TEXT("c:\\_restore\\archive") );
|
|
#endif
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
GetDSTemp( TCHAR ** pszStr )
|
|
{
|
|
static TCHAR str[MAX_PATH];
|
|
#if 0
|
|
*pszStr = str;
|
|
_tcscpy( *pszStr, _TEXT("c:\\_restore\\temp") );
|
|
#endif
|
|
return TRUE;
|
|
}
|
|
|
|
//
|
|
// CODEWORK: REMOVE NO ERROR DETECTION HACK.
|
|
//
|
|
|
|
BOOL CXMLFileListParser::PopulateReplaceEntries()
|
|
{
|
|
TCHAR szBuf[MAX_BUFFER];
|
|
DWORD dwSize;
|
|
HKEY hCurrentSettings=NULL;
|
|
HKEY hICWKey = NULL;
|
|
HRESULT hr=0;
|
|
BOOL fChgLogOpen=FALSE;
|
|
LPTSTR pszDSInfo=NULL;
|
|
TCHAR szLPN[MAX_BUFFER];
|
|
DWORD cbLPN;
|
|
|
|
TraceFunctEnter("CXMLFileListParser::PopulateReplaceEntries()");
|
|
|
|
|
|
// windows directory
|
|
|
|
if( GetWindowsDirectory( szBuf,MAX_BUFFER ) > MAX_BUFFER )
|
|
{
|
|
ErrorTrace(FILEID, "Error getting windir",0);
|
|
goto cleanup;
|
|
}
|
|
FixInconsistantBlackslash(szBuf);
|
|
SetEnvironmentVariable( _TEXT("WinDir"), szBuf );
|
|
|
|
// windows system directory
|
|
|
|
if( GetSystemDirectory( szBuf,MAX_BUFFER ) > MAX_BUFFER )
|
|
{
|
|
ErrorTrace(FILEID, "Error getting windir",0);
|
|
goto cleanup;
|
|
}
|
|
FixInconsistantBlackslash(szBuf);
|
|
SetEnvironmentVariable( _TEXT("WinSys"), szBuf );
|
|
|
|
// Alt Startup folder
|
|
|
|
if( SHGetSpecialFolderPath(NULL,szBuf, CSIDL_ALTSTARTUP ,FALSE) != TRUE )
|
|
{
|
|
DWORD dwError = GetLastError();
|
|
ErrorTrace(FILEID, "Error getting special folder: AltStartUp, error 0x%x", dwError);
|
|
lstrcpy(szBuf, DEFAULT_UNKNOWN);
|
|
lstrcat(szBuf, _TEXT("AltStartUp"));
|
|
}
|
|
FixInconsistantBlackslash(szBuf);
|
|
SetEnvironmentVariable( _TEXT("AltStartup"), szBuf );
|
|
|
|
//App data
|
|
if( SHGetSpecialFolderPath(NULL,szBuf, CSIDL_APPDATA ,FALSE) != TRUE )
|
|
{
|
|
DWORD dwError = GetLastError();
|
|
ErrorTrace(FILEID, "Error getting special folder: AppData, error 0x%x", dwError);
|
|
lstrcpy(szBuf, DEFAULT_UNKNOWN);
|
|
lstrcat(szBuf, _TEXT("AppData"));
|
|
}
|
|
FixInconsistantBlackslash(szBuf);
|
|
SetEnvironmentVariable( _TEXT("AppData"), szBuf );
|
|
|
|
|
|
// Recycle Bin ( BITBUCKET )
|
|
if( SHGetSpecialFolderPath(NULL,szBuf, CSIDL_BITBUCKET ,FALSE) != TRUE )
|
|
{
|
|
DWORD dwError = GetLastError();
|
|
ErrorTrace(FILEID, "Error getting special folder: RecycleBin, error 0x%x", dwError);
|
|
lstrcpy(szBuf, DEFAULT_UNKNOWN);
|
|
lstrcat(szBuf, _TEXT("RecycleBin"));
|
|
}
|
|
FixInconsistantBlackslash(szBuf);
|
|
SetEnvironmentVariable( _TEXT("RecycleBin"), szBuf );
|
|
|
|
// Common Desktop
|
|
|
|
if( SHGetSpecialFolderPath(NULL,szBuf, CSIDL_COMMON_DESKTOPDIRECTORY ,FALSE) != TRUE )
|
|
{
|
|
DWORD dwError = GetLastError();
|
|
ErrorTrace(FILEID, "Error getting special folder: CommonDesktop, error 0x%x", dwError);
|
|
lstrcpy(szBuf, DEFAULT_UNKNOWN);
|
|
lstrcat(szBuf, _TEXT("CommonDesktop"));
|
|
}
|
|
FixInconsistantBlackslash(szBuf);
|
|
SetEnvironmentVariable( _TEXT("CommonDesktop"), szBuf );
|
|
|
|
// Common Favorite
|
|
if( SHGetSpecialFolderPath(NULL,szBuf, CSIDL_COMMON_FAVORITES ,FALSE) != TRUE )
|
|
{
|
|
DWORD dwError = GetLastError();
|
|
ErrorTrace(FILEID, "Error getting special folder: CommonFavorites, error 0x%x", dwError);
|
|
lstrcpy(szBuf, DEFAULT_UNKNOWN);
|
|
lstrcat(szBuf, _TEXT("CommonFavorites"));
|
|
}
|
|
FixInconsistantBlackslash(szBuf);
|
|
SetEnvironmentVariable( _TEXT("CommonFavorites"), szBuf );
|
|
|
|
|
|
// Common Program groups
|
|
if( SHGetSpecialFolderPath(NULL,szBuf, CSIDL_COMMON_PROGRAMS,FALSE) != TRUE )
|
|
{
|
|
DWORD dwError = GetLastError();
|
|
ErrorTrace(FILEID, "Error getting special folder: CommonProgramGroups, error 0x%x", dwError);
|
|
lstrcpy(szBuf, DEFAULT_UNKNOWN);
|
|
lstrcat(szBuf, _TEXT("CommonProgramGroups"));
|
|
}
|
|
FixInconsistantBlackslash(szBuf);
|
|
SetEnvironmentVariable( _TEXT("CommonProgramGroups"), szBuf );
|
|
|
|
// Common start menu directory
|
|
if( SHGetSpecialFolderPath(NULL,szBuf, CSIDL_COMMON_STARTMENU, FALSE) != TRUE )
|
|
{
|
|
DWORD dwError = GetLastError();
|
|
ErrorTrace(FILEID, "Error getting special folder: CommonStartMenu, error 0x%x", dwError);
|
|
lstrcpy(szBuf, DEFAULT_UNKNOWN);
|
|
lstrcat(szBuf, _TEXT("CommonStartMenu"));
|
|
}
|
|
FixInconsistantBlackslash(szBuf);
|
|
SetEnvironmentVariable( _TEXT("CommonStartMenu"), szBuf );
|
|
|
|
// Common Startup Folder
|
|
if( SHGetSpecialFolderPath(NULL,szBuf, CSIDL_COMMON_STARTUP, FALSE) != TRUE )
|
|
{
|
|
DWORD dwError = GetLastError();
|
|
ErrorTrace(FILEID, "Error getting special folder: CommonStartUp, error 0x%x", dwError);
|
|
lstrcpy(szBuf, DEFAULT_UNKNOWN);
|
|
lstrcat(szBuf, _TEXT("CommonStartUp"));
|
|
}
|
|
FixInconsistantBlackslash(szBuf);
|
|
SetEnvironmentVariable( _TEXT("CommonStartUp"), szBuf );
|
|
|
|
// cookies folder
|
|
if( SHGetSpecialFolderPath(NULL,szBuf, CSIDL_COOKIES, FALSE) != TRUE )
|
|
{
|
|
DWORD dwError = GetLastError();
|
|
ErrorTrace(FILEID, "Error getting special folder: Cookies, error 0x%x", dwError);
|
|
GetWindowsDirectory(szBuf, MAX_BUFFER);
|
|
lstrcat(szBuf, _TEXT("\\Cookies"));
|
|
}
|
|
FixInconsistantBlackslash(szBuf);
|
|
SetEnvironmentVariable( _TEXT("Cookies"), szBuf );
|
|
|
|
// desktop directory
|
|
if( SHGetSpecialFolderPath(NULL,szBuf, CSIDL_DESKTOPDIRECTORY, FALSE) != TRUE )
|
|
{
|
|
DWORD dwError = GetLastError();
|
|
ErrorTrace(FILEID, "Error getting special folder: DesktopDirectory, error 0x%x", dwError);
|
|
GetWindowsDirectory(szBuf, MAX_BUFFER);
|
|
lstrcat(szBuf, _TEXT("\\Desktop"));
|
|
//goto cleanup;
|
|
}
|
|
FixInconsistantBlackslash(szBuf);
|
|
SetEnvironmentVariable( _TEXT("DesktopDirectory"), szBuf );
|
|
|
|
// favorites
|
|
if( SHGetSpecialFolderPath(NULL,szBuf, CSIDL_FAVORITES, FALSE) != TRUE )
|
|
{
|
|
DWORD dwError = GetLastError();
|
|
ErrorTrace(FILEID, "Error getting special folder: Favorites, error 0x%x", dwError);
|
|
GetWindowsDirectory(szBuf, MAX_BUFFER);
|
|
lstrcat(szBuf, _TEXT("\\Favorites"));
|
|
//goto cleanup;
|
|
}
|
|
FixInconsistantBlackslash(szBuf);
|
|
SetEnvironmentVariable( _TEXT("Favorites"), szBuf );
|
|
|
|
// favorites
|
|
if( SHGetSpecialFolderPath(NULL,szBuf, CSIDL_INTERNET_CACHE, FALSE) != TRUE )
|
|
{
|
|
DWORD dwError = GetLastError();
|
|
ErrorTrace(FILEID, "Error getting special folder: InternetCache, error 0x%x", dwError);
|
|
GetWindowsDirectory(szBuf, MAX_BUFFER);
|
|
lstrcat(szBuf, _TEXT("\\Temporary Internet Files"));
|
|
//goto cleanup;
|
|
}
|
|
FixInconsistantBlackslash(szBuf);
|
|
SetEnvironmentVariable( _TEXT("InternetCache"), szBuf );
|
|
|
|
// network neightbors
|
|
if( SHGetSpecialFolderPath(NULL,szBuf, CSIDL_NETHOOD, FALSE) != TRUE )
|
|
{
|
|
DWORD dwError = GetLastError();
|
|
ErrorTrace(FILEID, "Error getting special folder: Nethood, error 0x%x", dwError);
|
|
GetWindowsDirectory(szBuf, MAX_BUFFER);
|
|
lstrcat(szBuf, _TEXT("\\Nethood"));
|
|
//goto cleanup;
|
|
}
|
|
FixInconsistantBlackslash(szBuf);
|
|
SetEnvironmentVariable( _TEXT("NetHood"), szBuf );
|
|
|
|
// favorites
|
|
if( SHGetSpecialFolderPath(NULL,szBuf, CSIDL_PERSONAL, FALSE) != TRUE )
|
|
{
|
|
DWORD dwError = GetLastError();
|
|
ErrorTrace(FILEID, "Error getting special folder: PersonalDocuments, error 0x%x", dwError);
|
|
lstrcpy(szBuf, DEFAULT_UNKNOWN);
|
|
lstrcat(szBuf, _TEXT("PersonalDocuments"));
|
|
//goto cleanup;
|
|
}
|
|
FixInconsistantBlackslash(szBuf);
|
|
SetEnvironmentVariable( _TEXT("PersonalDocuments"), szBuf );
|
|
|
|
// favorites
|
|
if( SHGetSpecialFolderPath(NULL,szBuf, CSIDL_STARTMENU, FALSE) != TRUE )
|
|
{
|
|
DWORD dwError = GetLastError();
|
|
ErrorTrace(FILEID, "Error getting special folder: StartMenu, error 0x%x", dwError);
|
|
GetWindowsDirectory(szBuf, MAX_BUFFER);
|
|
lstrcat(szBuf, _TEXT("\\Start Menu"));
|
|
//goto cleanup;
|
|
}
|
|
FixInconsistantBlackslash(szBuf);
|
|
SetEnvironmentVariable( _TEXT("StartMenu"), szBuf );
|
|
|
|
// favorites
|
|
if( SHGetSpecialFolderPath(NULL,szBuf, CSIDL_TEMPLATES, FALSE) != TRUE )
|
|
{
|
|
DWORD dwError = GetLastError();
|
|
ErrorTrace(FILEID, "Error getting special folder: Templates, error 0x%x", dwError);
|
|
lstrcpy(szBuf, DEFAULT_UNKNOWN);
|
|
lstrcat(szBuf, _TEXT("Templates"));
|
|
//goto cleanup;
|
|
}
|
|
FixInconsistantBlackslash(szBuf);
|
|
SetEnvironmentVariable( _TEXT("Templates"), szBuf );
|
|
|
|
// favorites
|
|
if( SHGetSpecialFolderPath(NULL,szBuf, CSIDL_HISTORY, FALSE) != TRUE )
|
|
{
|
|
DWORD dwError = GetLastError();
|
|
ErrorTrace(FILEID, "Error getting special folder: History, error 0x%x", dwError);
|
|
GetWindowsDirectory(szBuf, MAX_BUFFER);
|
|
lstrcat(szBuf, _TEXT("\\History"));
|
|
//goto cleanup;
|
|
}
|
|
FixInconsistantBlackslash(szBuf);
|
|
SetEnvironmentVariable( _TEXT("History"), szBuf );
|
|
|
|
//hack
|
|
if( RegOpenKey( HKEY_LOCAL_MACHINE, _TEXT("Software\\Microsoft\\Windows\\CurrentVersion"), &hCurrentSettings) != ERROR_SUCCESS)
|
|
{
|
|
ErrorTrace(FILEID,"Error opening registry key to retrieve program files",0);
|
|
goto cleanup;
|
|
}
|
|
|
|
dwSize = MAX_BUFFER * sizeof(TCHAR);
|
|
if( RegQueryValueEx( hCurrentSettings, _TEXT("ProgramFilesDir"), NULL, NULL, (LPBYTE) szBuf, &dwSize) != ERROR_SUCCESS )
|
|
{
|
|
ErrorTrace(FILEID,"Error querying program files registry key.",0);
|
|
lstrcpy(szBuf, DEFAULT_UNKNOWN);
|
|
lstrcat(szBuf, _TEXT("ProgramFilesDir"));
|
|
// goto cleanup;
|
|
}
|
|
|
|
FixInconsistantBlackslash(szBuf);
|
|
SetEnvironmentVariable( _TEXT("ProgramFiles"), szBuf );
|
|
|
|
|
|
dwSize = MAX_BUFFER * sizeof(TCHAR);
|
|
if( RegQueryValueEx( hCurrentSettings, _TEXT("CommonFilesDir"), NULL, NULL, (LPBYTE) szBuf, &dwSize) != ERROR_SUCCESS )
|
|
{
|
|
ErrorTrace(FILEID,"Error querying common files registry key.",0);
|
|
lstrcpy(szBuf, DEFAULT_UNKNOWN);
|
|
lstrcat(szBuf, _TEXT("CommonFilesDir"));
|
|
// goto cleanup;
|
|
}
|
|
|
|
FixInconsistantBlackslash(szBuf);
|
|
SetEnvironmentVariable( _TEXT("CommonFiles"), szBuf );
|
|
|
|
|
|
// get the ICW dir path from the registry
|
|
if (ERROR_SUCCESS == RegOpenKeyEx(hCurrentSettings, ICW_REGKEY, 0, KEY_QUERY_VALUE, &hICWKey))
|
|
{
|
|
dwSize = MAX_BUFFER * sizeof(TCHAR);
|
|
if (ERROR_SUCCESS == RegQueryValueEx(hICWKey, _TEXT("Path"), NULL, NULL, (LPBYTE) szBuf, &dwSize))
|
|
{
|
|
// remove the extra ; in the path if it is there
|
|
dwSize = lstrlen(szBuf);
|
|
if (dwSize > 0)
|
|
{
|
|
if (szBuf[dwSize - 1] == TCHAR(';'))
|
|
{
|
|
szBuf[dwSize - 1] = TCHAR('\0');
|
|
}
|
|
}
|
|
|
|
// convert sfn to lfn
|
|
cbLPN = sizeof(szLPN)/sizeof(TCHAR);
|
|
if (cbLPN <= GetLongPathName(szBuf, szLPN, cbLPN)) // error
|
|
{
|
|
ErrorTrace(FILEID, "Error getting LPN for %s; error=%ld", szBuf, GetLastError());
|
|
lstrcpy(szLPN, DEFAULT_UNKNOWN);
|
|
lstrcat(szLPN, TEXT("ConnectionWizardDir"));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
lstrcpy(szLPN, DEFAULT_UNKNOWN);
|
|
lstrcat(szLPN, TEXT("ConnectionWizardDir"));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
lstrcpy(szLPN, DEFAULT_UNKNOWN);
|
|
lstrcat(szLPN, TEXT("ConnectionWizardDir"));
|
|
}
|
|
|
|
SetEnvironmentVariable(_TEXT("ConnectionWizard"), szLPN);
|
|
DebugTrace(FILEID, "ICW Path = %s", szLPN);
|
|
|
|
if (hICWKey)
|
|
{
|
|
RegCloseKey(hICWKey);
|
|
}
|
|
|
|
RegCloseKey( hCurrentSettings );
|
|
hCurrentSettings = NULL;
|
|
|
|
//
|
|
// System restore file stuff
|
|
//
|
|
|
|
if( GetDSRoot( &pszDSInfo ) == TRUE )
|
|
{
|
|
SetEnvironmentVariable( _TEXT("SRDataStoreRoot"), pszDSInfo );
|
|
}
|
|
else
|
|
{
|
|
DebugTrace(FILEID, "Error getting system restore root directory",0);
|
|
}
|
|
|
|
if( GetArchiveDir( &pszDSInfo ) == TRUE )
|
|
{
|
|
SetEnvironmentVariable( _TEXT("SRArchiveDir"), pszDSInfo );
|
|
}
|
|
else
|
|
{
|
|
DebugTrace(FILEID, "Error getting system restore archive directory",0);
|
|
}
|
|
|
|
if( GetDSTemp( &pszDSInfo ) == TRUE )
|
|
{
|
|
SetEnvironmentVariable( _TEXT("SRTempDir"), pszDSInfo );
|
|
}
|
|
else
|
|
{
|
|
DebugTrace(FILEID, "Error getting system restore temp directory",0);
|
|
}
|
|
|
|
|
|
// CODEWORK: Do this for real
|
|
SetEnvironmentVariable( _TEXT("DocAndSettingRoot"), _TEXT("C:\\Documents And Settings") );
|
|
|
|
TraceFunctLeave();
|
|
return TRUE;
|
|
cleanup:
|
|
if( hCurrentSettings )
|
|
{
|
|
RegCloseKey( hCurrentSettings );
|
|
}
|
|
// leave it, will be taken care of in the destructor
|
|
|
|
TraceFunctLeave();
|
|
return (FALSE);
|
|
}
|
|
|
|
//
|
|
// Misc utility functions
|
|
//
|
|
|
|
//
|
|
// We are assuming the buffer is big enough to fit the bstr.
|
|
// if it is not, we still
|
|
// free it but return false.
|
|
//
|
|
|
|
LONG
|
|
CXMLFileListParser::ConvertAndFreeBSTR(
|
|
BSTR bstrIn,
|
|
LPTSTR szpOut,
|
|
LONG lMaxBuf)
|
|
{
|
|
|
|
LONG lLen;
|
|
|
|
TraceFunctEnter("CXMLFileListParser::ConvertAndFreeBSTR");
|
|
|
|
//
|
|
// Initialize the output buffer
|
|
//
|
|
|
|
if (szpOut)
|
|
{
|
|
*szpOut = 0;
|
|
}
|
|
|
|
//
|
|
// make a copy and put it in our object.
|
|
//
|
|
|
|
_ASSERT( bstrIn );
|
|
_bstr_t BSTRBuffer( bstrIn, TRUE );
|
|
|
|
lLen = BSTRBuffer.length();
|
|
|
|
//
|
|
// not enough buffer space.
|
|
//
|
|
|
|
if( lLen > (lMaxBuf+1) )
|
|
{
|
|
// copy what we can out.
|
|
_tcsncpy( szpOut, BSTRBuffer.operator LPTSTR(), lMaxBuf );
|
|
szpOut[lMaxBuf] = 0;
|
|
SysFreeString( bstrIn );
|
|
TraceFunctLeave();
|
|
return( lLen + 1 );
|
|
|
|
}
|
|
|
|
_tcscpy( szpOut, BSTRBuffer.operator LPTSTR() );
|
|
|
|
//
|
|
// remove our BSTR
|
|
//
|
|
|
|
SysFreeString( bstrIn );
|
|
|
|
return( lMaxBuf );
|
|
}
|
|
|
|
LONG
|
|
CXMLFileListParser::TranslateType(TCHAR chType)
|
|
{
|
|
if( ( chType == _TEXT('i') ) || ( chType == _TEXT('I') ) )
|
|
{
|
|
return( INCLUDE_COLL );
|
|
}
|
|
else if( ( chType == _TEXT('e') ) || ( chType == _TEXT('E') ) )
|
|
{
|
|
return( EXCLUDE_COLL );
|
|
}
|
|
else if( ( chType == _TEXT('s') ) || ( chType == _TEXT('S') ) )
|
|
{
|
|
return( SNAPSHOT_COLL );
|
|
}
|
|
|
|
return( 0 );
|
|
}
|
|
|
|
void
|
|
CXMLFileListParser::DebugPrintTranslations()
|
|
{
|
|
LONG cl;
|
|
LPTSTR pszStr=NULL;
|
|
LPVOID pszBlock;
|
|
|
|
printf("File Name Translation Values ... \n");
|
|
|
|
pszBlock = GetEnvironmentStrings();
|
|
pszStr = (LPTSTR) pszBlock;
|
|
|
|
while( pszStr && *pszStr )
|
|
{
|
|
_tprintf(_TEXT("%s\n"), pszStr);
|
|
pszStr += (DWORD) StringLengthBytes(pszStr)/sizeof(TCHAR);
|
|
}
|
|
|
|
FreeEnvironmentStrings( (LPTSTR) pszBlock );
|
|
}
|
|
|
|
//
|
|
// A fix to the inconsistent blackslash behavior in the
|
|
// shell API.
|
|
//
|
|
|
|
void
|
|
FixInconsistantBlackslash(
|
|
LPTSTR pszDirectory)
|
|
{
|
|
LONG lLen;
|
|
|
|
_ASSERT( pszDirectory );
|
|
|
|
lLen = _tcslen( pszDirectory );
|
|
|
|
if( lLen <= 0 )
|
|
{
|
|
return;
|
|
}
|
|
|
|
if( pszDirectory[ lLen - 1 ] == _TEXT('\\') )
|
|
{
|
|
pszDirectory[lLen - 1] = 0;
|
|
}
|
|
}
|