Leaked source code of windows server 2003
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.

1688 lines
42 KiB

  1. //++
  2. //
  3. // Copyright (c) 1999 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // CXMLParser.c
  7. //
  8. // Abstract:
  9. // This file contains the functions used by System restore in
  10. // order to real the XML encoded list of protected files. It
  11. // also performs translations between symbols like %windir% to
  12. // C:\windows
  13. //
  14. // Revision History:
  15. // Eugene Mesgar (eugenem) 6/16/99
  16. // created
  17. // Kanwaljit Marok (kmarok ) 6/06/00
  18. // rewritten for Whistler
  19. //--
  20. #include <windows.h>
  21. #include <windowsx.h>
  22. #include <stdlib.h>
  23. #include <stdio.h>
  24. #include <tchar.h>
  25. #include <comdef.h>
  26. #include <crtdbg.h>
  27. #include <dbgtrace.h>
  28. #include <shlobj.h>
  29. #include <shlwapi.h>
  30. #include <winreg.h>
  31. #include <commonlib.h>
  32. #include "msxml.h"
  33. #include "xmlparser.h"
  34. #include "utils.h"
  35. #ifdef THIS_FILE
  36. #undef THIS_FILE
  37. #endif
  38. static char __szTraceSourceFile[] = __FILE__;
  39. #define THIS_FILE __szTraceSourceFile
  40. //
  41. // Local Define Section
  42. //
  43. #define MAX_BUF 1024
  44. #define FILEID 0
  45. //
  46. // SAFERELEASE does a safe release on COM interfaces.
  47. // Checks to see if not null, if so, calls release
  48. // method on the interface. Then sets the interface to null.
  49. //
  50. #define SAFERELEASE(p) if (p) {(p)->Release(); p = NULL;} else ;
  51. //
  52. // Default string to be assigned to environment variables if
  53. // cannot assign real folder
  54. //
  55. #define DEFAULT_UNKNOWN _TEXT("C:\\Unknown_")
  56. #define ICW_REGKEY _TEXT("App Paths\\ICWCONN1.EXE")
  57. //
  58. // Local Utility functions
  59. //
  60. void FixInconsistantBlackslash(LPTSTR pszDirectory);
  61. //
  62. // The constructor
  63. // Desc: Zero's all memory
  64. //
  65. CXMLFileListParser::CXMLFileListParser()
  66. {
  67. LONG lLoop;
  68. m_pDoc = NULL;
  69. for(lLoop = 0;lLoop < NUM_FILE_TYPES;lLoop++)
  70. {
  71. m_pDir[lLoop] = m_pExt[lLoop] = m_pFiles[lLoop] = NULL;
  72. }
  73. m_chDefaultType = _TEXT('i');
  74. m_clComInitialized = 0;
  75. }
  76. CXMLFileListParser::~CXMLFileListParser()
  77. {
  78. LONG lLoop;
  79. for(lLoop = 0;lLoop < NUM_FILE_TYPES;lLoop++)
  80. {
  81. SAFERELEASE( m_pDir[lLoop] );
  82. SAFERELEASE( m_pExt[lLoop] );
  83. SAFERELEASE( m_pFiles[lLoop] );
  84. }
  85. SAFERELEASE( m_pDoc );
  86. //
  87. // we need to do this in a loop
  88. // so we don't leek resources with refcounting
  89. //
  90. for( lLoop = 0; lLoop < m_clComInitialized ;lLoop++)
  91. {
  92. CoUninitialize( ); // lets kill COM!
  93. }
  94. }
  95. //
  96. // Init overloaded
  97. //
  98. // Main intialization sequence
  99. //
  100. // 1) Initializes The Com Space and Creates an XML document
  101. // 2) Loads in the specified file into the XML document object
  102. // 3) Takes the document loads all the collections to populate
  103. // our sub collections ( each list gets its own heading)
  104. // 4) Sets up our Search->Replace settings
  105. //
  106. BOOL CXMLFileListParser::Init(LPCTSTR pszFile)
  107. {
  108. if(!Init())
  109. {
  110. return FALSE;
  111. }
  112. if(!ParseFile(pszFile))
  113. {
  114. return FALSE;
  115. }
  116. if(!LoadCollections())
  117. {
  118. return FALSE;
  119. }
  120. if( !PopulateReplaceEntries() )
  121. {
  122. return FALSE;
  123. }
  124. return TRUE;
  125. }
  126. BOOL CXMLFileListParser::Init()
  127. {
  128. HRESULT hr;
  129. LONG clLoop;
  130. TraceFunctEnter("Init");
  131. //
  132. // If we are reinitializing, make sure we free up old
  133. // resources and clean up our internal variables
  134. //
  135. for( clLoop = 0; clLoop < NUM_FILE_TYPES; clLoop++)
  136. {
  137. SAFERELEASE( m_pDir[clLoop] );
  138. SAFERELEASE( m_pExt[clLoop] );
  139. SAFERELEASE( m_pFiles[clLoop] );
  140. }
  141. memset(m_adwVersion,0,sizeof(DWORD) * 4);
  142. //
  143. // Initialize our COM apartment space
  144. //
  145. hr = CoInitialize(NULL);
  146. m_clComInitialized++;
  147. //
  148. // S_FALSE means the COM apartment space has been initliazed
  149. // for this procss already
  150. //
  151. if( (hr != S_OK) && (hr != S_FALSE) )
  152. {
  153. ErrorTrace(FILEID,"CoInitialize Failed 0x%x", hr);
  154. m_clComInitialized--;
  155. goto cleanup;
  156. }
  157. //
  158. // Create an instance of our XML document object
  159. //
  160. hr = CoCreateInstance(CLSID_XMLDocument, NULL, CLSCTX_INPROC_SERVER,
  161. IID_IXMLDocument, (void**)&m_pDoc);
  162. if( !m_pDoc || !SUCCEEDED(hr) )
  163. {
  164. ErrorTrace(FILEID,"CoCreateInstance Failed 0x%x", GetLastError());
  165. goto cleanup;
  166. }
  167. TraceFunctLeave();
  168. return(TRUE);
  169. cleanup:
  170. SAFERELEASE( m_pDoc );
  171. TraceFunctLeave();
  172. return(FALSE);
  173. }
  174. //
  175. // Method: LoadCollections()
  176. //
  177. // Desc:
  178. // This method goes through the XML file and finds the
  179. // <FILES>, <DIRECTORIES>, <EXTENSIONS>, <DEFTYPE>, <VERSION>
  180. // high level tags and then runs LoadOneCollection() on each of
  181. // them in order to
  182. // populate the high level m_pDir, m_pFiles, m_pExt arrays ( which
  183. // have collections for
  184. // include, exclude, sfp, etc )..
  185. //
  186. BOOL CXMLFileListParser::LoadCollections()
  187. {
  188. IXMLElement *pRoot = NULL, *pTempElement = NULL;
  189. IXMLElementCollection *pChildren = NULL;
  190. IDispatch *pDispatch = NULL;
  191. BSTR stTagName;
  192. HRESULT hr;
  193. BSTR stTagValue;
  194. TCHAR szBuf[MAX_BUFFER];
  195. LONG clLoop, lCollectionSize;
  196. TraceFunctEnter("CXMLFileListParser::LoadCollections");
  197. _ASSERT(m_pDoc);
  198. if( ( hr = m_pDoc->get_root( &pRoot) ) != S_OK )
  199. {
  200. ErrorTrace(FILEID, "IXMLDocument::GetRoot failed 0x%x",GetLastError());
  201. goto cleanup;
  202. }
  203. if( ( hr = pRoot->get_tagName( &stTagName ) ) != S_OK )
  204. {
  205. ErrorTrace(FILEID, "IXMLElement::get_tagName failed 0x%x", hr );
  206. goto cleanup;
  207. }
  208. if( ConvertAndFreeBSTR( stTagName, szBuf, MAX_BUFFER ) > MAX_BUFFER )
  209. {
  210. ErrorTrace(FILEID, "BSTR too large for buffer", 0);
  211. goto cleanup;
  212. }
  213. //
  214. // compare filesLPCT
  215. //
  216. if( _tcsicmp( _TEXT("PCHealthProtect"), szBuf ) )
  217. {
  218. ErrorTrace(FILEID, "Malformed XML file",0);
  219. goto cleanup;
  220. }
  221. if( ( hr = pRoot->get_children( &pChildren ) ) != S_OK )
  222. {
  223. ErrorTrace(FILEID,"IXMLElement::get_children failed 0x%x", hr);
  224. goto cleanup;
  225. }
  226. //
  227. // we no longer need the root;
  228. //
  229. SAFERELEASE(pRoot);
  230. if( (hr = pChildren->get_length(&lCollectionSize) ) != S_OK )
  231. {
  232. DebugTrace(FILEID,"Error Finding Length 0x%x", hr );
  233. goto cleanup;
  234. }
  235. //
  236. // lets get references to all the sub collections
  237. //
  238. for( clLoop = 0; clLoop < lCollectionSize; clLoop++)
  239. {
  240. VARIANT v1, v2;
  241. v1.vt = VT_I4;
  242. v2.vt = VT_EMPTY;
  243. v1.lVal = clLoop;
  244. //
  245. // get a item from the collection
  246. //
  247. if( (hr = pChildren->item(v1,v2, &pDispatch) ) != S_OK )
  248. {
  249. ErrorTrace(FILEID, "Error pChildren->item 0x%x", hr);
  250. goto cleanup;
  251. }
  252. if( ( hr = pDispatch->QueryInterface(IID_IXMLElement,
  253. (void **) &pTempElement) ) != S_OK )
  254. {
  255. ErrorTrace(FILEID, "Error IDispatch::QueryInterface 0x%d", hr);
  256. goto cleanup;
  257. }
  258. //
  259. // lets see which collection it is
  260. //
  261. if( (hr = pTempElement->get_tagName( &stTagName ) ) != S_OK )
  262. {
  263. DebugTrace(FILEID, "Error in get_tagName 0x%x", hr );
  264. goto cleanup;
  265. }
  266. if( ConvertAndFreeBSTR( stTagName, szBuf, MAX_BUFFER ) > MAX_BUFFER )
  267. {
  268. ErrorTrace(FILEID, "BSTR too large for buffer", 0);
  269. goto cleanup;
  270. }
  271. if( !_tcsicmp( _TEXT("DIRECTORIES"), szBuf ) )
  272. {
  273. if( !LoadOneCollection(pTempElement, m_pDir ) )
  274. {
  275. ErrorTrace(FILEID,"Error Loading Collection",0);
  276. goto cleanup;
  277. }
  278. }
  279. else if( !_tcsicmp( _TEXT( "FILES"), szBuf ) )
  280. {
  281. if( !LoadOneCollection(pTempElement, m_pFiles ) )
  282. {
  283. ErrorTrace(FILEID,"Error Loading Collection",0);
  284. goto cleanup;
  285. }
  286. }
  287. else if( !_tcsicmp( _TEXT( "EXTENSIONS"), szBuf ) )
  288. {
  289. if( !LoadOneCollection(pTempElement, m_pExt ) )
  290. {
  291. ErrorTrace(FILEID,"Error Loading Collection",0);
  292. goto cleanup;
  293. }
  294. }
  295. else if( !_tcsicmp( _TEXT( "VERSION"), szBuf ) )
  296. {
  297. if( ParseVersion(pTempElement) == FALSE )
  298. {
  299. goto cleanup;
  300. }
  301. }
  302. else if( !_tcsicmp( _TEXT( "DEFTYPE"), szBuf ) )
  303. {
  304. if( ( hr = pTempElement->get_text( &stTagValue ) ) != S_OK )
  305. {
  306. ErrorTrace(FILEID, "Error in IXMLElement::get_text 0x%x", hr);
  307. goto cleanup;
  308. }
  309. if( ConvertAndFreeBSTR( stTagValue,
  310. szBuf,
  311. MAX_BUFFER ) > MAX_BUFFER )
  312. {
  313. ErrorTrace(FILEID, "Less space in BSTR to string buffer", 0);
  314. goto cleanup;
  315. }
  316. //
  317. // make sure trail, leaing spaces don't get us messed up;
  318. //
  319. TrimString(szBuf);
  320. //
  321. // empty string?
  322. //
  323. if( szBuf[0] == 0 )
  324. {
  325. ErrorTrace(FILEID, "Empty string passed to default type.",0);
  326. goto cleanup;
  327. }
  328. m_chDefaultType = szBuf[0];
  329. }
  330. else
  331. {
  332. ErrorTrace(FILEID, "Undefiend XML tag in file.",0);
  333. goto cleanup;
  334. }
  335. SAFERELEASE( pTempElement);
  336. SAFERELEASE( pDispatch );
  337. }
  338. SAFERELEASE( pChildren );
  339. TraceFunctLeave();
  340. return TRUE;
  341. cleanup:
  342. SAFERELEASE( pTempElement );
  343. SAFERELEASE( pDispatch );
  344. SAFERELEASE( pRoot );
  345. SAFERELEASE( pChildren );
  346. TraceFunctLeave();
  347. return FALSE;
  348. }
  349. //
  350. // Method: LoadOneCollection(IXMLElement *, IXMLElementCollection **)
  351. //
  352. // Desc: Takes a high level node (like <FILES>) and then gets all
  353. // the sub include,exclude,sfp collections and sets them up in the
  354. // pCol array (usually passed a member variable like m_pDir, m_pFiles,
  355. // etc).
  356. //
  357. BOOL CXMLFileListParser::LoadOneCollection(
  358. IXMLElement *pColHead,
  359. IXMLElementCollection **pCol )
  360. {
  361. HRESULT hr;
  362. IXMLElementCollection *pChildren = NULL;
  363. IXMLElement *pTempElement = NULL;
  364. IDispatch *pDispatch = NULL;
  365. LONG lCollectionSize, clLoop;
  366. BSTR stTagName;
  367. TCHAR szBuf[MAX_BUFFER];
  368. _ASSERT( pColHead );
  369. TraceFunctEnter("CXMLFileListParser::LoadOneCollection");
  370. //
  371. // Lets make sure we don't have a section called <FILES></FILES>
  372. //
  373. if( (hr = pColHead->get_children( &pChildren )) != S_OK )
  374. {
  375. ErrorTrace(FILEID,"Empty <FILES,EXT,DIRECTORY,etc section",0);
  376. TraceFunctLeave();
  377. return(TRUE);
  378. }
  379. if( (hr = pChildren->get_length( &lCollectionSize ) ) != S_OK )
  380. {
  381. DebugTrace(FILEID, "Error getting collection size. 0x%x", hr );
  382. goto cleanup;
  383. }
  384. for( clLoop = 0; clLoop < lCollectionSize; clLoop++)
  385. {
  386. //
  387. // Set up OLE style variant varaibles to loop through all the entires
  388. //
  389. VARIANT v1, v2;
  390. v1.vt = VT_I4;
  391. v2.vt = VT_EMPTY;
  392. v1.lVal = clLoop;
  393. //
  394. // get a item from the collection
  395. //
  396. if( (hr = pChildren->item(v1,v2, &pDispatch) ) != S_OK )
  397. {
  398. ErrorTrace(FILEID, "Error pChildren->item 0x%x", hr);
  399. goto cleanup;
  400. }
  401. if( ( hr = pDispatch->QueryInterface(IID_IXMLElement,
  402. (void **) &pTempElement) ) != S_OK )
  403. {
  404. ErrorTrace(FILEID, "Error IDispatch::QueryInterface 0x%d", hr);
  405. goto cleanup;
  406. }
  407. SAFERELEASE( pDispatch );
  408. //
  409. // lets see which collection it is
  410. //
  411. if( (hr = pTempElement->get_tagName( &stTagName ) ) != S_OK )
  412. {
  413. ErrorTrace(FILEID, "Error in get_tagName 0x%x", hr);
  414. goto cleanup;
  415. }
  416. if( ConvertAndFreeBSTR( stTagName, szBuf, MAX_BUFFER) > MAX_BUFFER )
  417. {
  418. ErrorTrace(FILEID, "Not enough space to convert BString.",0);
  419. goto cleanup;
  420. }
  421. if( !_tcsicmp( _TEXT("INCLUDE"), szBuf ) )
  422. {
  423. if( (hr = pTempElement->get_children( & pCol[INCLUDE_COLL] ) )
  424. != S_OK )
  425. {
  426. DebugTrace(FILEID,"Error in IXMLElement::get_children 0x%x",hr);
  427. goto cleanup;
  428. }
  429. }
  430. else if( !_tcsicmp( _TEXT( "EXCLUDE"), szBuf ) )
  431. {
  432. if( (hr = pTempElement->get_children( & pCol[EXCLUDE_COLL] ) )
  433. != S_OK )
  434. {
  435. DebugTrace(FILEID,"Error in IXMLElement::get_children 0x%x",hr);
  436. goto cleanup;
  437. }
  438. }
  439. else if( !_tcsicmp( _TEXT( "SNAPSHOT"), szBuf ) )
  440. {
  441. if( (hr = pTempElement->get_children( & pCol[SNAPSHOT_COLL] ) )
  442. != S_OK )
  443. {
  444. DebugTrace(FILEID,"Error in IXMLElement::get_children 0x%x",hr);
  445. goto cleanup;
  446. }
  447. }
  448. else
  449. {
  450. ErrorTrace(FILEID, "Undefiend XML tag in file.",0);
  451. goto cleanup;
  452. }
  453. SAFERELEASE( pTempElement);
  454. }
  455. SAFERELEASE( pChildren );
  456. TraceFunctLeave();
  457. return TRUE;
  458. cleanup:
  459. SAFERELEASE( pTempElement );
  460. SAFERELEASE( pDispatch );
  461. SAFERELEASE( pChildren );
  462. TraceFunctLeave();
  463. return FALSE;
  464. }
  465. //
  466. // Function: ParseFile(LPCTSR pszFile)
  467. // Desc: Loads a file into the member variable m_pDoc.
  468. //
  469. BOOL CXMLFileListParser::ParseFile(LPCTSTR pszFile)
  470. {
  471. BSTR pBURL=NULL;
  472. _bstr_t FileBuffer( pszFile );
  473. HRESULT hr;
  474. TraceFunctEnter("ParseFile");
  475. pBURL = FileBuffer.copy();
  476. if( !pBURL )
  477. {
  478. ErrorTrace(FILEID, "Error allocating space for a BSTR", 0);
  479. goto cleanup;
  480. }
  481. if( (hr = m_pDoc->put_URL( pBURL ) ) != S_OK )
  482. {
  483. DebugTrace(FILEID, "Error m_pDoc->putUrl %0x%x", hr );
  484. goto cleanup;
  485. }
  486. if( pBURL )
  487. {
  488. SysFreeString( pBURL );
  489. }
  490. TraceFunctLeave();
  491. return(TRUE);
  492. cleanup:
  493. if( pBURL )
  494. {
  495. SysFreeString( pBURL );
  496. }
  497. TraceFunctLeave();
  498. return(FALSE);
  499. }
  500. //
  501. // Function: ParseVersion(IXMLElement *pVerElement)
  502. //
  503. //
  504. // Desc: This funciton is called from LoadCollections() when it hits the element
  505. // containing the XML files version. It takes an IXMLElement
  506. // object and extracts the version into the m_adwVersion array
  507. //
  508. //
  509. BOOL CXMLFileListParser::ParseVersion(IXMLElement *pVerElement)
  510. {
  511. HRESULT hr;
  512. BSTR stTagValue;
  513. TCHAR szTagValue[MAX_BUFFER];
  514. TCHAR szBuf[256];
  515. LONG clElement;
  516. TraceFunctEnter("CXMLFileListParser::ParseVersionElement");
  517. if( (hr = pVerElement->get_text( & stTagValue ) ) != S_OK )
  518. {
  519. DebugTrace(FILEID, "Error in IXMLElement::get_text 0x%x", hr );
  520. goto cleanup;
  521. }
  522. if( ConvertAndFreeBSTR( stTagValue, szTagValue, MAX_BUFFER ) > MAX_BUFFER )
  523. {
  524. ErrorTrace(FILEID, "Error conveting the Bstring. Not enough buffer.",0);
  525. goto cleanup;
  526. }
  527. for( clElement = 0; clElement < 4; clElement++ )
  528. {
  529. if( GetField(szTagValue,szBuf,clElement,_TEXT('.') ) == 0 )
  530. break;
  531. m_adwVersion[clElement] = _ttoi( szBuf );
  532. }
  533. TraceFunctLeave();
  534. return(TRUE);
  535. cleanup:
  536. TraceFunctLeave();
  537. return FALSE;
  538. }
  539. //
  540. // XML Tree traversal and general accessor functions
  541. // Exposed Wrappers: GetDirectory, GetFile, GetExt
  542. // GetDirectoryCount, GetFileCount, GetExtCount
  543. //
  544. //
  545. // RETURN VALUES FOR THE GET FUNCTIONS:
  546. // lBufMax -- filename was copied OK
  547. // 0 -- serious error occoured
  548. // > lBufMax -- the number of TCHARs you really need
  549. //
  550. //
  551. // BOOL *pfDisable is for the special
  552. // "protected directory" feature in the VxD.
  553. //
  554. LONG
  555. CXMLFileListParser::GetDirectory(
  556. LONG ilElement,
  557. LPTSTR pszBuf,
  558. LONG lBufMax,
  559. TCHAR chType,
  560. BOOL *pfDisable)
  561. {
  562. LONG lReturnValue=0;
  563. LONG lType;
  564. TraceFunctEnter("CXMLFileListParser::GetDirectory");
  565. //
  566. // get the array index of this file type
  567. //
  568. lType = TranslateType( chType );
  569. if( !m_pDoc || !m_pDir[lType] )
  570. {
  571. TraceFunctLeave();
  572. return 0;
  573. }
  574. if( (lReturnValue = GetFileInfo(
  575. m_pDir[lType],
  576. ilElement,
  577. pszBuf,
  578. lBufMax,
  579. pfDisable)) != lBufMax)
  580. {
  581. goto cleanup;
  582. }
  583. if( (lReturnValue = SearchAndReplace(pszBuf, lBufMax) ) != lBufMax )
  584. {
  585. goto cleanup;
  586. }
  587. CharUpper( pszBuf );
  588. //
  589. // make sure there are no (lead/trail spaces/tabs)
  590. //
  591. TrimString( pszBuf );
  592. cleanup:
  593. TraceFunctLeave();
  594. return( lReturnValue );
  595. }
  596. LONG
  597. CXMLFileListParser::GetDirectory(
  598. LONG ilElement,
  599. LPTSTR pszBuf,
  600. LONG lBufMax,
  601. TCHAR chType)
  602. {
  603. return( GetDirectory( ilElement, pszBuf, lBufMax, chType, NULL ) );
  604. }
  605. LONG
  606. CXMLFileListParser::GetExt(
  607. LONG ilElement,
  608. LPTSTR pszBuf,
  609. LONG lBufMax,
  610. TCHAR chType)
  611. {
  612. LONG lReturnValue=0;
  613. LONG lType;
  614. TraceFunctEnter("CXMLFileListParser::GetExt");
  615. lType = TranslateType( chType );
  616. if( !m_pDoc || !m_pExt[lType] )
  617. {
  618. TraceFunctLeave();
  619. return 0;
  620. }
  621. if( (lReturnValue = GetFileInfo(m_pExt[lType],
  622. ilElement,
  623. pszBuf,
  624. lBufMax,
  625. NULL)) != lBufMax)
  626. {
  627. goto cleanup;
  628. }
  629. if( (lReturnValue = SearchAndReplace(pszBuf, lBufMax) ) != lBufMax )
  630. {
  631. goto cleanup;
  632. }
  633. CharUpper( pszBuf );
  634. //
  635. // make sure there are no (lead/trail spaces/tabs)
  636. //
  637. TrimString( pszBuf );
  638. cleanup:
  639. TraceFunctLeave();
  640. return( lReturnValue );
  641. }
  642. LONG
  643. CXMLFileListParser::GetFile(
  644. LONG ilElement,
  645. LPTSTR pszBuf,
  646. LONG lBufMax,
  647. TCHAR chType)
  648. {
  649. LONG lReturnValue=0;
  650. LONG lType;
  651. TraceFunctEnter("CXMLFileListParser::GetFile");
  652. lType = TranslateType( chType );
  653. if( !m_pDoc || !m_pFiles[lType] )
  654. {
  655. TraceFunctLeave();
  656. return 0;
  657. }
  658. if( (lReturnValue = GetFileInfo(m_pFiles[lType],
  659. ilElement,
  660. pszBuf,
  661. lBufMax,
  662. NULL)) != lBufMax)
  663. {
  664. goto cleanup;
  665. }
  666. if( (lReturnValue = SearchAndReplace(pszBuf, lBufMax) ) != lBufMax )
  667. {
  668. goto cleanup;
  669. }
  670. CharUpper( pszBuf );
  671. //
  672. // make sure there are no (lead/trail spaces/tabs)
  673. //
  674. TrimString( pszBuf );
  675. cleanup:
  676. TraceFunctLeave();
  677. return( lReturnValue );
  678. }
  679. //
  680. // GetDirectory/File/ExtCount functions.
  681. // These functions give you the number of entries in a specific collection.
  682. // For example: GetFileCount(SNAPSHOT_TYPE) will return the numbert
  683. // of entries in the FILES main heading, which are under the SNAPSHOT
  684. // subheading in the XML file.
  685. //
  686. LONG
  687. CXMLFileListParser::GetDirectoryCount(
  688. TCHAR chType)
  689. {
  690. LONG lReturnValue;
  691. TraceFunctEnter("CXMLFileListParser::GetDirectoryCount");
  692. lReturnValue = GetCollectionSize( m_pDir[TranslateType(chType)] );
  693. TraceFunctLeave();
  694. return( lReturnValue );
  695. }
  696. LONG
  697. CXMLFileListParser::GetExtCount(
  698. TCHAR chType)
  699. {
  700. LONG lReturnValue;
  701. TraceFunctEnter("CXMLFileListParser::GetExtCount");
  702. lReturnValue = GetCollectionSize( m_pExt[TranslateType(chType)] );
  703. TraceFunctLeave();
  704. return( lReturnValue );
  705. }
  706. LONG
  707. CXMLFileListParser::GetFileCount(
  708. TCHAR chType)
  709. {
  710. LONG lReturnValue;
  711. TraceFunctEnter("CXMLFileListParser::GetFileCount");
  712. lReturnValue = GetCollectionSize( m_pFiles[TranslateType(chType)] );
  713. TraceFunctLeave();
  714. return( lReturnValue );
  715. }
  716. //
  717. // Main internal functions used to get by the wrappers.
  718. //
  719. // GetCollectionSize, GetFileInfo
  720. //
  721. //
  722. LONG
  723. CXMLFileListParser::GetCollectionSize(
  724. IXMLElementCollection *pCol)
  725. {
  726. LONG lCollectionSize;
  727. HRESULT hr;
  728. TraceFunctEnter("CXMLFileListParser::GetCollectionSize");
  729. if( pCol == NULL ) {
  730. TraceFunctLeave();
  731. return 0;
  732. }
  733. if( (hr = pCol->get_length(&lCollectionSize) ) != S_OK )
  734. {
  735. DebugTrace(FILEID, "Error Finding Length 0x%x", hr );
  736. goto cleanup;
  737. }
  738. TraceFunctLeave();
  739. return(lCollectionSize);
  740. cleanup:
  741. TraceFunctLeave();
  742. return 0;
  743. }
  744. //
  745. // RETURN VALUES:
  746. // lBufMax -- filename was copied OK
  747. // 0 -- serious error occoured
  748. // > lBufMax -- the number in TCHAR's that you need.
  749. //
  750. LONG
  751. CXMLFileListParser::GetFileInfo(
  752. IXMLElementCollection *pCol,
  753. LONG ilElement,
  754. LPTSTR pszBuf,
  755. LONG lBufMax,
  756. BOOL *pfDisable)
  757. {
  758. HRESULT hr;
  759. LONG lLen, lCollectionSize=0, clLoop, lReturnValue=0;
  760. VARIANT v1, v2;
  761. // OLE/COM BSTR variables and helper classes
  762. BSTR stTagValue;
  763. TCHAR szValueBuffer[MAX_BUFFER];
  764. // COM interfaces
  765. IDispatch *pDispatch = NULL;
  766. IXMLElement *pTempElement = NULL;
  767. IXMLElementCollection *pChildren = NULL;
  768. TraceFunctEnter("CXMLFileListParser::GetFileInfo");
  769. //
  770. // Basic assumptions of the code.
  771. //
  772. _ASSERT(pCol);
  773. _ASSERT(pszBuf || !lBufMax);
  774. _ASSERT(pchType);
  775. //
  776. // Set up to make sure protection code is clean
  777. // Test to see if we have an in-range request.
  778. //
  779. if( (hr = pCol->get_length(&lCollectionSize) ) != S_OK )
  780. {
  781. DebugTrace(FILEID, "Error Finding Length 0x%x", hr );
  782. goto cleanup;
  783. }
  784. if( ilElement >= lCollectionSize )
  785. {
  786. ErrorTrace(FILEID,
  787. "CXMLFileListParser::GetFileInfo (Element out of range)",
  788. 0);
  789. goto cleanup;
  790. }
  791. v1.vt = VT_I4;
  792. v1.lVal = ilElement;
  793. v2.vt = VT_EMPTY;
  794. //
  795. // get a item from the collection
  796. //
  797. if( (hr = pCol->item(v1,v2, &pDispatch) ) != S_OK )
  798. {
  799. ErrorTrace(FILEID, "Error pChildren->item 0x%x", hr);
  800. goto cleanup;
  801. }
  802. if( ( hr = pDispatch->QueryInterface(IID_IXMLElement,
  803. (void **) &pTempElement) ) != S_OK )
  804. {
  805. ErrorTrace(FILEID, "Error IDispatch::QueryInterface 0x%d", hr);
  806. goto cleanup;
  807. }
  808. SAFERELEASE( pDispatch );
  809. if( (hr = pTempElement->get_text( & stTagValue ) ) != S_OK )
  810. {
  811. DebugTrace(FILEID, "Error in IXMLElement::get_text 0x%x", hr );
  812. goto cleanup;
  813. }
  814. if( ( lLen = ConvertAndFreeBSTR( stTagValue, szValueBuffer, MAX_BUFFER ) ) >
  815. MAX_BUFFER )
  816. {
  817. lReturnValue = lLen + 1;
  818. goto cleanup;
  819. }
  820. _tcscpy( pszBuf, szValueBuffer );
  821. if( pfDisable )
  822. {
  823. _bstr_t AttrName( _TEXT("DISABLE") );
  824. VARIANT AttrValue;
  825. *pfDisable = FALSE;
  826. //
  827. // clear the variant
  828. //
  829. VariantInit( &AttrValue );
  830. hr = pTempElement->getAttribute( AttrName, &AttrValue );
  831. //
  832. // who cares what the property name is
  833. //
  834. if( hr == S_OK )
  835. {
  836. *pfDisable = TRUE;
  837. VariantClear( &AttrValue );
  838. }
  839. }
  840. SAFERELEASE( pTempElement );
  841. lReturnValue = lBufMax;
  842. TraceFunctLeave();
  843. return(lReturnValue);
  844. cleanup:
  845. SAFERELEASE( pTempElement );
  846. SAFERELEASE( pDispatch );
  847. // what about BSTR's?
  848. TraceFunctLeave();
  849. return(lReturnValue);
  850. }
  851. BOOL
  852. CXMLFileListParser::GetVersion(
  853. LPDWORD pdwVersion)
  854. {
  855. TraceFunctEnter("CXMLFileListParser::GetVersion");
  856. _ASSERT( pdwVersion );
  857. memcpy( pdwVersion, m_adwVersion, sizeof(DWORD) * 4 );
  858. TraceFunctLeave();
  859. return(TRUE);
  860. }
  861. TCHAR
  862. CXMLFileListParser::GetDefaultType()
  863. {
  864. return( (TCHAR) CharUpper( (LPTSTR) m_chDefaultType) );
  865. }
  866. LONG
  867. CXMLFileListParser::SearchAndReplace(
  868. LPTSTR szBuf,
  869. LONG lMaxBuf)
  870. {
  871. TCHAR szTempBuf[MAX_BUFFER];
  872. DWORD dwResult;
  873. LONG lReturn = 0;
  874. TraceFunctEnter("CXMLFileListParser::SearchAndReplace");
  875. dwResult = ExpandEnvironmentStrings( szBuf, szTempBuf, lMaxBuf);
  876. if( 0 == dwResult )
  877. {
  878. DWORD dwError;
  879. dwError = GetLastError();
  880. ErrorTrace(FILEID, "Error in search and replace ec-%d", dwError);
  881. lReturn = 0;
  882. goto cleanup;
  883. }
  884. if( dwResult > (lMaxBuf*sizeof(TCHAR) ) )
  885. {
  886. ErrorTrace(FILEID, "Buffer too small in Search and replace.",0);
  887. lReturn = dwResult;
  888. goto cleanup;
  889. }
  890. _tcscpy( szBuf, szTempBuf );
  891. lReturn = lMaxBuf;
  892. cleanup:
  893. TraceFunctLeave();
  894. return lReturn;
  895. }
  896. BOOL
  897. CXMLFileListParser::DepopulateReplaceEntries()
  898. {
  899. LONG clLoop;
  900. TraceFunctEnter("CXMLFileListParser::DepopulateReplaceEntries");
  901. // This code shouldn't do anything anymore in the new system
  902. TraceFunctLeave();
  903. return TRUE;
  904. }
  905. BOOL
  906. GetDSRoot( TCHAR ** pszStr )
  907. {
  908. static WCHAR str[MAX_PATH];
  909. *pszStr = str;
  910. *str = 0;
  911. #ifdef UNICODE
  912. _stprintf( *pszStr, _TEXT("*:\\_restore.%s"), GetMachineGuid());
  913. #else
  914. _stprintf( *pszStr, _TEXT("*:\\_restore") );
  915. #endif
  916. return TRUE;
  917. }
  918. BOOL
  919. GetArchiveDir( TCHAR ** pszStr )
  920. {
  921. static TCHAR str[MAX_PATH];
  922. #if 0
  923. *pszStr = str;
  924. _tcscpy( *pszStr, _TEXT("c:\\_restore\\archive") );
  925. #endif
  926. return TRUE;
  927. }
  928. BOOL
  929. GetDSTemp( TCHAR ** pszStr )
  930. {
  931. static TCHAR str[MAX_PATH];
  932. #if 0
  933. *pszStr = str;
  934. _tcscpy( *pszStr, _TEXT("c:\\_restore\\temp") );
  935. #endif
  936. return TRUE;
  937. }
  938. //
  939. // CODEWORK: REMOVE NO ERROR DETECTION HACK.
  940. //
  941. BOOL CXMLFileListParser::PopulateReplaceEntries()
  942. {
  943. TCHAR szBuf[MAX_BUFFER];
  944. DWORD dwSize;
  945. HKEY hCurrentSettings=NULL;
  946. HKEY hICWKey = NULL;
  947. HRESULT hr=0;
  948. BOOL fChgLogOpen=FALSE;
  949. LPTSTR pszDSInfo=NULL;
  950. TCHAR szLPN[MAX_BUFFER];
  951. DWORD cbLPN;
  952. TraceFunctEnter("CXMLFileListParser::PopulateReplaceEntries()");
  953. // windows directory
  954. if( GetWindowsDirectory( szBuf,MAX_BUFFER ) > MAX_BUFFER )
  955. {
  956. ErrorTrace(FILEID, "Error getting windir",0);
  957. goto cleanup;
  958. }
  959. FixInconsistantBlackslash(szBuf);
  960. SetEnvironmentVariable( _TEXT("WinDir"), szBuf );
  961. // windows system directory
  962. if( GetSystemDirectory( szBuf,MAX_BUFFER ) > MAX_BUFFER )
  963. {
  964. ErrorTrace(FILEID, "Error getting windir",0);
  965. goto cleanup;
  966. }
  967. FixInconsistantBlackslash(szBuf);
  968. SetEnvironmentVariable( _TEXT("WinSys"), szBuf );
  969. // Alt Startup folder
  970. if( SHGetSpecialFolderPath(NULL,szBuf, CSIDL_ALTSTARTUP ,FALSE) != TRUE )
  971. {
  972. DWORD dwError = GetLastError();
  973. ErrorTrace(FILEID, "Error getting special folder: AltStartUp, error 0x%x", dwError);
  974. lstrcpy(szBuf, DEFAULT_UNKNOWN);
  975. lstrcat(szBuf, _TEXT("AltStartUp"));
  976. }
  977. FixInconsistantBlackslash(szBuf);
  978. SetEnvironmentVariable( _TEXT("AltStartup"), szBuf );
  979. //App data
  980. if( SHGetSpecialFolderPath(NULL,szBuf, CSIDL_APPDATA ,FALSE) != TRUE )
  981. {
  982. DWORD dwError = GetLastError();
  983. ErrorTrace(FILEID, "Error getting special folder: AppData, error 0x%x", dwError);
  984. lstrcpy(szBuf, DEFAULT_UNKNOWN);
  985. lstrcat(szBuf, _TEXT("AppData"));
  986. }
  987. FixInconsistantBlackslash(szBuf);
  988. SetEnvironmentVariable( _TEXT("AppData"), szBuf );
  989. // Recycle Bin ( BITBUCKET )
  990. if( SHGetSpecialFolderPath(NULL,szBuf, CSIDL_BITBUCKET ,FALSE) != TRUE )
  991. {
  992. DWORD dwError = GetLastError();
  993. ErrorTrace(FILEID, "Error getting special folder: RecycleBin, error 0x%x", dwError);
  994. lstrcpy(szBuf, DEFAULT_UNKNOWN);
  995. lstrcat(szBuf, _TEXT("RecycleBin"));
  996. }
  997. FixInconsistantBlackslash(szBuf);
  998. SetEnvironmentVariable( _TEXT("RecycleBin"), szBuf );
  999. // Common Desktop
  1000. if( SHGetSpecialFolderPath(NULL,szBuf, CSIDL_COMMON_DESKTOPDIRECTORY ,FALSE) != TRUE )
  1001. {
  1002. DWORD dwError = GetLastError();
  1003. ErrorTrace(FILEID, "Error getting special folder: CommonDesktop, error 0x%x", dwError);
  1004. lstrcpy(szBuf, DEFAULT_UNKNOWN);
  1005. lstrcat(szBuf, _TEXT("CommonDesktop"));
  1006. }
  1007. FixInconsistantBlackslash(szBuf);
  1008. SetEnvironmentVariable( _TEXT("CommonDesktop"), szBuf );
  1009. // Common Favorite
  1010. if( SHGetSpecialFolderPath(NULL,szBuf, CSIDL_COMMON_FAVORITES ,FALSE) != TRUE )
  1011. {
  1012. DWORD dwError = GetLastError();
  1013. ErrorTrace(FILEID, "Error getting special folder: CommonFavorites, error 0x%x", dwError);
  1014. lstrcpy(szBuf, DEFAULT_UNKNOWN);
  1015. lstrcat(szBuf, _TEXT("CommonFavorites"));
  1016. }
  1017. FixInconsistantBlackslash(szBuf);
  1018. SetEnvironmentVariable( _TEXT("CommonFavorites"), szBuf );
  1019. // Common Program groups
  1020. if( SHGetSpecialFolderPath(NULL,szBuf, CSIDL_COMMON_PROGRAMS,FALSE) != TRUE )
  1021. {
  1022. DWORD dwError = GetLastError();
  1023. ErrorTrace(FILEID, "Error getting special folder: CommonProgramGroups, error 0x%x", dwError);
  1024. lstrcpy(szBuf, DEFAULT_UNKNOWN);
  1025. lstrcat(szBuf, _TEXT("CommonProgramGroups"));
  1026. }
  1027. FixInconsistantBlackslash(szBuf);
  1028. SetEnvironmentVariable( _TEXT("CommonProgramGroups"), szBuf );
  1029. // Common start menu directory
  1030. if( SHGetSpecialFolderPath(NULL,szBuf, CSIDL_COMMON_STARTMENU, FALSE) != TRUE )
  1031. {
  1032. DWORD dwError = GetLastError();
  1033. ErrorTrace(FILEID, "Error getting special folder: CommonStartMenu, error 0x%x", dwError);
  1034. lstrcpy(szBuf, DEFAULT_UNKNOWN);
  1035. lstrcat(szBuf, _TEXT("CommonStartMenu"));
  1036. }
  1037. FixInconsistantBlackslash(szBuf);
  1038. SetEnvironmentVariable( _TEXT("CommonStartMenu"), szBuf );
  1039. // Common Startup Folder
  1040. if( SHGetSpecialFolderPath(NULL,szBuf, CSIDL_COMMON_STARTUP, FALSE) != TRUE )
  1041. {
  1042. DWORD dwError = GetLastError();
  1043. ErrorTrace(FILEID, "Error getting special folder: CommonStartUp, error 0x%x", dwError);
  1044. lstrcpy(szBuf, DEFAULT_UNKNOWN);
  1045. lstrcat(szBuf, _TEXT("CommonStartUp"));
  1046. }
  1047. FixInconsistantBlackslash(szBuf);
  1048. SetEnvironmentVariable( _TEXT("CommonStartUp"), szBuf );
  1049. // cookies folder
  1050. if( SHGetSpecialFolderPath(NULL,szBuf, CSIDL_COOKIES, FALSE) != TRUE )
  1051. {
  1052. DWORD dwError = GetLastError();
  1053. ErrorTrace(FILEID, "Error getting special folder: Cookies, error 0x%x", dwError);
  1054. GetWindowsDirectory(szBuf, MAX_BUFFER);
  1055. lstrcat(szBuf, _TEXT("\\Cookies"));
  1056. }
  1057. FixInconsistantBlackslash(szBuf);
  1058. SetEnvironmentVariable( _TEXT("Cookies"), szBuf );
  1059. // desktop directory
  1060. if( SHGetSpecialFolderPath(NULL,szBuf, CSIDL_DESKTOPDIRECTORY, FALSE) != TRUE )
  1061. {
  1062. DWORD dwError = GetLastError();
  1063. ErrorTrace(FILEID, "Error getting special folder: DesktopDirectory, error 0x%x", dwError);
  1064. GetWindowsDirectory(szBuf, MAX_BUFFER);
  1065. lstrcat(szBuf, _TEXT("\\Desktop"));
  1066. //goto cleanup;
  1067. }
  1068. FixInconsistantBlackslash(szBuf);
  1069. SetEnvironmentVariable( _TEXT("DesktopDirectory"), szBuf );
  1070. // favorites
  1071. if( SHGetSpecialFolderPath(NULL,szBuf, CSIDL_FAVORITES, FALSE) != TRUE )
  1072. {
  1073. DWORD dwError = GetLastError();
  1074. ErrorTrace(FILEID, "Error getting special folder: Favorites, error 0x%x", dwError);
  1075. GetWindowsDirectory(szBuf, MAX_BUFFER);
  1076. lstrcat(szBuf, _TEXT("\\Favorites"));
  1077. //goto cleanup;
  1078. }
  1079. FixInconsistantBlackslash(szBuf);
  1080. SetEnvironmentVariable( _TEXT("Favorites"), szBuf );
  1081. // favorites
  1082. if( SHGetSpecialFolderPath(NULL,szBuf, CSIDL_INTERNET_CACHE, FALSE) != TRUE )
  1083. {
  1084. DWORD dwError = GetLastError();
  1085. ErrorTrace(FILEID, "Error getting special folder: InternetCache, error 0x%x", dwError);
  1086. GetWindowsDirectory(szBuf, MAX_BUFFER);
  1087. lstrcat(szBuf, _TEXT("\\Temporary Internet Files"));
  1088. //goto cleanup;
  1089. }
  1090. FixInconsistantBlackslash(szBuf);
  1091. SetEnvironmentVariable( _TEXT("InternetCache"), szBuf );
  1092. // network neightbors
  1093. if( SHGetSpecialFolderPath(NULL,szBuf, CSIDL_NETHOOD, FALSE) != TRUE )
  1094. {
  1095. DWORD dwError = GetLastError();
  1096. ErrorTrace(FILEID, "Error getting special folder: Nethood, error 0x%x", dwError);
  1097. GetWindowsDirectory(szBuf, MAX_BUFFER);
  1098. lstrcat(szBuf, _TEXT("\\Nethood"));
  1099. //goto cleanup;
  1100. }
  1101. FixInconsistantBlackslash(szBuf);
  1102. SetEnvironmentVariable( _TEXT("NetHood"), szBuf );
  1103. // favorites
  1104. if( SHGetSpecialFolderPath(NULL,szBuf, CSIDL_PERSONAL, FALSE) != TRUE )
  1105. {
  1106. DWORD dwError = GetLastError();
  1107. ErrorTrace(FILEID, "Error getting special folder: PersonalDocuments, error 0x%x", dwError);
  1108. lstrcpy(szBuf, DEFAULT_UNKNOWN);
  1109. lstrcat(szBuf, _TEXT("PersonalDocuments"));
  1110. //goto cleanup;
  1111. }
  1112. FixInconsistantBlackslash(szBuf);
  1113. SetEnvironmentVariable( _TEXT("PersonalDocuments"), szBuf );
  1114. // favorites
  1115. if( SHGetSpecialFolderPath(NULL,szBuf, CSIDL_STARTMENU, FALSE) != TRUE )
  1116. {
  1117. DWORD dwError = GetLastError();
  1118. ErrorTrace(FILEID, "Error getting special folder: StartMenu, error 0x%x", dwError);
  1119. GetWindowsDirectory(szBuf, MAX_BUFFER);
  1120. lstrcat(szBuf, _TEXT("\\Start Menu"));
  1121. //goto cleanup;
  1122. }
  1123. FixInconsistantBlackslash(szBuf);
  1124. SetEnvironmentVariable( _TEXT("StartMenu"), szBuf );
  1125. // favorites
  1126. if( SHGetSpecialFolderPath(NULL,szBuf, CSIDL_TEMPLATES, FALSE) != TRUE )
  1127. {
  1128. DWORD dwError = GetLastError();
  1129. ErrorTrace(FILEID, "Error getting special folder: Templates, error 0x%x", dwError);
  1130. lstrcpy(szBuf, DEFAULT_UNKNOWN);
  1131. lstrcat(szBuf, _TEXT("Templates"));
  1132. //goto cleanup;
  1133. }
  1134. FixInconsistantBlackslash(szBuf);
  1135. SetEnvironmentVariable( _TEXT("Templates"), szBuf );
  1136. // favorites
  1137. if( SHGetSpecialFolderPath(NULL,szBuf, CSIDL_HISTORY, FALSE) != TRUE )
  1138. {
  1139. DWORD dwError = GetLastError();
  1140. ErrorTrace(FILEID, "Error getting special folder: History, error 0x%x", dwError);
  1141. GetWindowsDirectory(szBuf, MAX_BUFFER);
  1142. lstrcat(szBuf, _TEXT("\\History"));
  1143. //goto cleanup;
  1144. }
  1145. FixInconsistantBlackslash(szBuf);
  1146. SetEnvironmentVariable( _TEXT("History"), szBuf );
  1147. //hack
  1148. if( RegOpenKey( HKEY_LOCAL_MACHINE, _TEXT("Software\\Microsoft\\Windows\\CurrentVersion"), &hCurrentSettings) != ERROR_SUCCESS)
  1149. {
  1150. ErrorTrace(FILEID,"Error opening registry key to retrieve program files",0);
  1151. goto cleanup;
  1152. }
  1153. dwSize = MAX_BUFFER * sizeof(TCHAR);
  1154. if( RegQueryValueEx( hCurrentSettings, _TEXT("ProgramFilesDir"), NULL, NULL, (LPBYTE) szBuf, &dwSize) != ERROR_SUCCESS )
  1155. {
  1156. ErrorTrace(FILEID,"Error querying program files registry key.",0);
  1157. lstrcpy(szBuf, DEFAULT_UNKNOWN);
  1158. lstrcat(szBuf, _TEXT("ProgramFilesDir"));
  1159. // goto cleanup;
  1160. }
  1161. FixInconsistantBlackslash(szBuf);
  1162. SetEnvironmentVariable( _TEXT("ProgramFiles"), szBuf );
  1163. dwSize = MAX_BUFFER * sizeof(TCHAR);
  1164. if( RegQueryValueEx( hCurrentSettings, _TEXT("CommonFilesDir"), NULL, NULL, (LPBYTE) szBuf, &dwSize) != ERROR_SUCCESS )
  1165. {
  1166. ErrorTrace(FILEID,"Error querying common files registry key.",0);
  1167. lstrcpy(szBuf, DEFAULT_UNKNOWN);
  1168. lstrcat(szBuf, _TEXT("CommonFilesDir"));
  1169. // goto cleanup;
  1170. }
  1171. FixInconsistantBlackslash(szBuf);
  1172. SetEnvironmentVariable( _TEXT("CommonFiles"), szBuf );
  1173. // get the ICW dir path from the registry
  1174. if (ERROR_SUCCESS == RegOpenKeyEx(hCurrentSettings, ICW_REGKEY, 0, KEY_QUERY_VALUE, &hICWKey))
  1175. {
  1176. dwSize = MAX_BUFFER * sizeof(TCHAR);
  1177. if (ERROR_SUCCESS == RegQueryValueEx(hICWKey, _TEXT("Path"), NULL, NULL, (LPBYTE) szBuf, &dwSize))
  1178. {
  1179. // remove the extra ; in the path if it is there
  1180. dwSize = lstrlen(szBuf);
  1181. if (dwSize > 0)
  1182. {
  1183. if (szBuf[dwSize - 1] == TCHAR(';'))
  1184. {
  1185. szBuf[dwSize - 1] = TCHAR('\0');
  1186. }
  1187. }
  1188. // convert sfn to lfn
  1189. cbLPN = sizeof(szLPN)/sizeof(TCHAR);
  1190. if (cbLPN <= GetLongPathName(szBuf, szLPN, cbLPN)) // error
  1191. {
  1192. ErrorTrace(FILEID, "Error getting LPN for %s; error=%ld", szBuf, GetLastError());
  1193. lstrcpy(szLPN, DEFAULT_UNKNOWN);
  1194. lstrcat(szLPN, TEXT("ConnectionWizardDir"));
  1195. }
  1196. }
  1197. else
  1198. {
  1199. lstrcpy(szLPN, DEFAULT_UNKNOWN);
  1200. lstrcat(szLPN, TEXT("ConnectionWizardDir"));
  1201. }
  1202. }
  1203. else
  1204. {
  1205. lstrcpy(szLPN, DEFAULT_UNKNOWN);
  1206. lstrcat(szLPN, TEXT("ConnectionWizardDir"));
  1207. }
  1208. SetEnvironmentVariable(_TEXT("ConnectionWizard"), szLPN);
  1209. DebugTrace(FILEID, "ICW Path = %s", szLPN);
  1210. if (hICWKey)
  1211. {
  1212. RegCloseKey(hICWKey);
  1213. }
  1214. RegCloseKey( hCurrentSettings );
  1215. hCurrentSettings = NULL;
  1216. //
  1217. // System restore file stuff
  1218. //
  1219. if( GetDSRoot( &pszDSInfo ) == TRUE )
  1220. {
  1221. SetEnvironmentVariable( _TEXT("SRDataStoreRoot"), pszDSInfo );
  1222. }
  1223. else
  1224. {
  1225. DebugTrace(FILEID, "Error getting system restore root directory",0);
  1226. }
  1227. if( GetArchiveDir( &pszDSInfo ) == TRUE )
  1228. {
  1229. SetEnvironmentVariable( _TEXT("SRArchiveDir"), pszDSInfo );
  1230. }
  1231. else
  1232. {
  1233. DebugTrace(FILEID, "Error getting system restore archive directory",0);
  1234. }
  1235. if( GetDSTemp( &pszDSInfo ) == TRUE )
  1236. {
  1237. SetEnvironmentVariable( _TEXT("SRTempDir"), pszDSInfo );
  1238. }
  1239. else
  1240. {
  1241. DebugTrace(FILEID, "Error getting system restore temp directory",0);
  1242. }
  1243. // CODEWORK: Do this for real
  1244. SetEnvironmentVariable( _TEXT("DocAndSettingRoot"), _TEXT("C:\\Documents And Settings") );
  1245. TraceFunctLeave();
  1246. return TRUE;
  1247. cleanup:
  1248. if( hCurrentSettings )
  1249. {
  1250. RegCloseKey( hCurrentSettings );
  1251. }
  1252. // leave it, will be taken care of in the destructor
  1253. TraceFunctLeave();
  1254. return (FALSE);
  1255. }
  1256. //
  1257. // Misc utility functions
  1258. //
  1259. //
  1260. // We are assuming the buffer is big enough to fit the bstr.
  1261. // if it is not, we still
  1262. // free it but return false.
  1263. //
  1264. LONG
  1265. CXMLFileListParser::ConvertAndFreeBSTR(
  1266. BSTR bstrIn,
  1267. LPTSTR szpOut,
  1268. LONG lMaxBuf)
  1269. {
  1270. LONG lLen;
  1271. TraceFunctEnter("CXMLFileListParser::ConvertAndFreeBSTR");
  1272. //
  1273. // Initialize the output buffer
  1274. //
  1275. if (szpOut)
  1276. {
  1277. *szpOut = 0;
  1278. }
  1279. //
  1280. // make a copy and put it in our object.
  1281. //
  1282. _ASSERT( bstrIn );
  1283. _bstr_t BSTRBuffer( bstrIn, TRUE );
  1284. lLen = BSTRBuffer.length();
  1285. //
  1286. // not enough buffer space.
  1287. //
  1288. if( lLen > (lMaxBuf+1) )
  1289. {
  1290. // copy what we can out.
  1291. _tcsncpy( szpOut, BSTRBuffer.operator LPTSTR(), lMaxBuf );
  1292. szpOut[lMaxBuf] = 0;
  1293. SysFreeString( bstrIn );
  1294. TraceFunctLeave();
  1295. return( lLen + 1 );
  1296. }
  1297. _tcscpy( szpOut, BSTRBuffer.operator LPTSTR() );
  1298. //
  1299. // remove our BSTR
  1300. //
  1301. SysFreeString( bstrIn );
  1302. return( lMaxBuf );
  1303. }
  1304. LONG
  1305. CXMLFileListParser::TranslateType(TCHAR chType)
  1306. {
  1307. if( ( chType == _TEXT('i') ) || ( chType == _TEXT('I') ) )
  1308. {
  1309. return( INCLUDE_COLL );
  1310. }
  1311. else if( ( chType == _TEXT('e') ) || ( chType == _TEXT('E') ) )
  1312. {
  1313. return( EXCLUDE_COLL );
  1314. }
  1315. else if( ( chType == _TEXT('s') ) || ( chType == _TEXT('S') ) )
  1316. {
  1317. return( SNAPSHOT_COLL );
  1318. }
  1319. return( 0 );
  1320. }
  1321. void
  1322. CXMLFileListParser::DebugPrintTranslations()
  1323. {
  1324. LONG cl;
  1325. LPTSTR pszStr=NULL;
  1326. LPVOID pszBlock;
  1327. printf("File Name Translation Values ... \n");
  1328. pszBlock = GetEnvironmentStrings();
  1329. pszStr = (LPTSTR) pszBlock;
  1330. while( pszStr && *pszStr )
  1331. {
  1332. _tprintf(_TEXT("%s\n"), pszStr);
  1333. pszStr += (DWORD) StringLengthBytes(pszStr)/sizeof(TCHAR);
  1334. }
  1335. FreeEnvironmentStrings( (LPTSTR) pszBlock );
  1336. }
  1337. //
  1338. // A fix to the inconsistent blackslash behavior in the
  1339. // shell API.
  1340. //
  1341. void
  1342. FixInconsistantBlackslash(
  1343. LPTSTR pszDirectory)
  1344. {
  1345. LONG lLen;
  1346. _ASSERT( pszDirectory );
  1347. lLen = _tcslen( pszDirectory );
  1348. if( lLen <= 0 )
  1349. {
  1350. return;
  1351. }
  1352. if( pszDirectory[ lLen - 1 ] == _TEXT('\\') )
  1353. {
  1354. pszDirectory[lLen - 1] = 0;
  1355. }
  1356. }