Source code of Windows XP (NT5)
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.

1017 lines
26 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1996-1998 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // AnswerFile.cpp
  7. //
  8. // Abstract:
  9. // This is the implementation file for the CAnswerFileSection class and
  10. // its' contained classes.
  11. //
  12. // Author:
  13. // C. Brent Thomas a-brentt
  14. //
  15. // Revision History:
  16. //
  17. // 24-Sep-1998 original
  18. //
  19. // Notes:
  20. //
  21. // The classes implemented in this file include:
  22. //
  23. // CAnswerFileSection
  24. // CAnswerFileEntry
  25. // CParameterListEntry
  26. //
  27. // I consciously chose not to use MFC because I expect cluster setup to
  28. // move away from MFC (probably to ATL) when it gets rewritten.
  29. //
  30. /////////////////////////////////////////////////////////////////////////////
  31. #include <windows.h>
  32. #include <setupapi.h>
  33. #include <tchar.h>
  34. #include "AnswerFile.h"
  35. // The following set of functions implements the CParameterList class.
  36. /////////////////////////////////////////////////////////////////////////////
  37. //++
  38. //
  39. // CParameterListEntry
  40. //
  41. // Routine Description:
  42. // This is the constructor for the CParameterListEntry class.
  43. //
  44. // Arguments:
  45. // None
  46. //
  47. // Return Value:
  48. // None
  49. //
  50. //--
  51. /////////////////////////////////////////////////////////////////////////////
  52. CParameterListEntry::CParameterListEntry()
  53. {
  54. // Initialize the pointer to the next CParameterListEntry object to NULL.
  55. m_pNextParameter = NULL; // The CParameterList object that this data
  56. // member points to will be allocated with the
  57. // new operator.
  58. // Initialize the pointer to the parameter string to NULL.
  59. m_ptszParameter = NULL; // The string that this data member points to
  60. // will be allocated with the new operator.
  61. }
  62. /////////////////////////////////////////////////////////////////////////////
  63. //++
  64. //
  65. // ~CParameterListEntry
  66. //
  67. // Routine Description:
  68. // This is the destructor for the CParameterListEntry class.
  69. //
  70. // Arguments:
  71. // None
  72. //
  73. // Return Value:
  74. // None
  75. //
  76. //--
  77. /////////////////////////////////////////////////////////////////////////////
  78. CParameterListEntry::~CParameterListEntry()
  79. {
  80. // Delete the parameter string.
  81. if ( m_ptszParameter != NULL )
  82. {
  83. delete [] m_ptszParameter;
  84. }
  85. // Delete any other CParameterListEntry objects that may be in this list.
  86. if ( m_pNextParameter != NULL )
  87. {
  88. delete m_pNextParameter;
  89. }
  90. }
  91. /////////////////////////////////////////////////////////////////////////////
  92. //++
  93. //
  94. // SetParameterString
  95. //
  96. // Routine Description:
  97. // This function allocates memory for a parameter string, initializes the
  98. // string, ans sets the m_ptszParameter data member of a CParameterListEntry
  99. // object.
  100. //
  101. // Arguments:
  102. // ptszParameter - the input string
  103. //
  104. // Return Value:
  105. // TRUE - indicates success
  106. // FALSE - indicates and error occured
  107. //
  108. //--
  109. /////////////////////////////////////////////////////////////////////////////
  110. BOOL CParameterListEntry::SetParameterString( LPTSTR ptszParameter )
  111. {
  112. BOOL fReturnValue;
  113. // Has the parameter string already been set?
  114. if ( m_ptszParameter != NULL )
  115. {
  116. // Free the existing parameter string. It will be replaced below.
  117. delete m_ptszParameter;
  118. }
  119. // Is the parameter meaningfull?
  120. if ( (ptszParameter != NULL) && (*ptszParameter != TEXT( '\0' )) )
  121. {
  122. // Allocate memory for the parameter string ans save its' address.
  123. m_ptszParameter = new TCHAR[_tcslen( ptszParameter ) + 1];
  124. _tcscpy( m_ptszParameter, ptszParameter );
  125. }
  126. else
  127. {
  128. m_ptszParameter = NULL;
  129. }
  130. fReturnValue = TRUE;
  131. return ( fReturnValue );
  132. }
  133. /////////////////////////////////////////////////////////////////////////////
  134. //++
  135. //
  136. // GetparameterStringPointer
  137. //
  138. // Routine Description:
  139. // This function returns the contents of the m_ptszParameter member of
  140. // a CParameterListEntry object.
  141. //
  142. // Arguments:
  143. // None
  144. //
  145. // Return Value:
  146. // A pointer to a parameter string.
  147. //
  148. //--
  149. /////////////////////////////////////////////////////////////////////////////
  150. LPTSTR CParameterListEntry::GetParameterStringPointer( void )
  151. {
  152. return ( m_ptszParameter );
  153. }
  154. /////////////////////////////////////////////////////////////////////////////
  155. //++
  156. //
  157. // SetNextParameterPointer
  158. //
  159. // Routine Description:
  160. // This function sets the m_pNextParameter data member of a CParameterListEntry object.
  161. //
  162. // Arguments:
  163. // pParameterListPointer - Points to a CParameterListEntry object.
  164. //
  165. // Return Value:
  166. // TRUE - indicates success
  167. // FALSE - indicates error
  168. //
  169. //--
  170. /////////////////////////////////////////////////////////////////////////////
  171. BOOL CParameterListEntry::SetNextParameterPointer( CParameterListEntry * pParameterListPointer )
  172. {
  173. BOOL fReturnValue;
  174. // If the parameter list pointer has already been set, free it. It will get replaced below.
  175. if ( m_pNextParameter != NULL )
  176. {
  177. delete m_pNextParameter;
  178. }
  179. // Set the parameter list pointer member.
  180. m_pNextParameter = pParameterListPointer;
  181. fReturnValue = TRUE;
  182. return ( fReturnValue );
  183. }
  184. /////////////////////////////////////////////////////////////////////////////
  185. //++
  186. //
  187. // GetParameterListPointer
  188. //
  189. // Routine Description:
  190. // This function returns the m_pNextParameter data member of a CParameterListEntry object.
  191. //
  192. // Arguments:
  193. // None
  194. //
  195. // Return Value:
  196. // The value of the m_pNextParameter data member of a CParameterListEntry object.
  197. //
  198. //--
  199. /////////////////////////////////////////////////////////////////////////////
  200. CParameterListEntry * CParameterListEntry::GetParameterListPointer( void )
  201. {
  202. return ( m_pNextParameter );
  203. }
  204. // The following set of functions implements the CAnswerFileEntry class.
  205. /////////////////////////////////////////////////////////////////////////////
  206. //++
  207. //
  208. // CAnswerFileEntry
  209. //
  210. // Routine Description:
  211. // This is the constructor for the CAnswerFileEntry class.
  212. //
  213. // Arguments:
  214. // None
  215. //
  216. // Return Value:
  217. // None
  218. //
  219. //--
  220. /////////////////////////////////////////////////////////////////////////////
  221. CAnswerFileEntry::CAnswerFileEntry()
  222. {
  223. // Initialize the pointer to the next CAnswerFileEntry object to NULL.
  224. m_pNextEntry = NULL; // The CAnswerFileEntry object that this
  225. // data member points to will be allocated
  226. // with the new operator.
  227. // Initialize the pointer to the key string to NULL.
  228. m_ptszKey = NULL; // The string that this data member points to
  229. // will be allocated with the new operator.
  230. // Initialize the pointer to the list of parameters to NULL;
  231. m_pParameterList = NULL; // The CParameterList object that this data
  232. // member points to will be allocated with the
  233. // new operator.
  234. // Initialize the number of parameters to zero;
  235. m_xParameterCount = 0;
  236. }
  237. /////////////////////////////////////////////////////////////////////////////
  238. //++
  239. //
  240. // ~CAnswerFileEntry
  241. //
  242. // Routine Description:
  243. // This is the destructor for the CAnswerFileEntry class.
  244. //
  245. // Arguments:
  246. // None
  247. //
  248. // Return Value:
  249. // None
  250. //
  251. //--
  252. /////////////////////////////////////////////////////////////////////////////
  253. CAnswerFileEntry::~CAnswerFileEntry()
  254. {
  255. // Delete the key string.
  256. if ( m_ptszKey != NULL )
  257. {
  258. delete [] m_ptszKey;
  259. }
  260. // Delete the parameter list.
  261. if ( m_pParameterList != NULL )
  262. {
  263. delete m_pParameterList;
  264. }
  265. // Delete any other CAnswerFileEntry objects that may be in this list.
  266. if ( m_pNextEntry != NULL )
  267. {
  268. delete m_pNextEntry;
  269. }
  270. }
  271. /////////////////////////////////////////////////////////////////////////////
  272. //++
  273. //
  274. // SetKey
  275. //
  276. // Routine Description:
  277. // This function sets the m_ptszKey data member of a CAnswerFileEntry object.
  278. // It allocates memory for the string, initializes the string, and sets the
  279. // m_ptszKey member to point to the string.
  280. //
  281. // Arguments:
  282. // ptszKey - the string to which the m_ptszKey member should be set.
  283. //
  284. // Return Value:
  285. // TRUE - indicates success
  286. // FALSE - indicates that an error occured
  287. //
  288. //--
  289. /////////////////////////////////////////////////////////////////////////////
  290. BOOL CAnswerFileEntry::SetKey( LPTSTR ptszKey )
  291. {
  292. BOOL fReturnValue;
  293. // If the key string has previously been set delete it.
  294. if ( m_ptszKey != NULL )
  295. {
  296. delete m_ptszKey;
  297. }
  298. // Set the key string.
  299. // Is the parameter meaningfull?
  300. if ( (ptszKey != NULL) && (*ptszKey != TEXT( '\0' )) )
  301. {
  302. // Allocate memory for the string and save its' address.
  303. m_ptszKey = new TCHAR[_tcslen(ptszKey) + 1];
  304. // Store the key string.
  305. _tcscpy( m_ptszKey, ptszKey );
  306. }
  307. else
  308. {
  309. m_ptszKey = NULL;
  310. }
  311. fReturnValue = TRUE;
  312. return ( fReturnValue );
  313. }
  314. /////////////////////////////////////////////////////////////////////////////
  315. //++
  316. //
  317. // GetKeyPointer
  318. //
  319. // Routine Description:
  320. // This function returns the contents of the m_ptszKey member of a
  321. // CAnswerFileEntry object.
  322. //
  323. // Arguments:
  324. // None
  325. //
  326. // Return Value:
  327. // A pointer to the key for a CAnswerFileEntry object.
  328. //
  329. //--
  330. /////////////////////////////////////////////////////////////////////////////
  331. LPTSTR CAnswerFileEntry::GetKeyPointer( void )
  332. {
  333. return ( m_ptszKey );
  334. }
  335. /////////////////////////////////////////////////////////////////////////////
  336. //++
  337. //
  338. // SetParameterCount
  339. //
  340. // Routine Description:
  341. // This function sets the m_xParameterCount member of a CAnswerFileEntry object.
  342. //
  343. // Arguments:
  344. // xParameterCount - the number of parameters in the answer file entry
  345. //
  346. // Return Value:
  347. // TRUE - indicates success
  348. // FALSE - indicates an error occured
  349. //
  350. //--
  351. /////////////////////////////////////////////////////////////////////////////
  352. BOOL CAnswerFileEntry::SetParameterCount( int xParameterCount )
  353. {
  354. BOOL fReturnValue;
  355. m_xParameterCount = xParameterCount;
  356. fReturnValue = TRUE;
  357. return ( fReturnValue );
  358. }
  359. /////////////////////////////////////////////////////////////////////////////
  360. //++
  361. //
  362. // GetParameterCount
  363. //
  364. // Routine Description:
  365. // This function returns the m_xParameterCount member of a CAnswerFileEntry object.
  366. //
  367. // Arguments:
  368. // None
  369. //
  370. // Return Value:
  371. // the number of parameters read from the answer file for this entry
  372. //
  373. //--
  374. /////////////////////////////////////////////////////////////////////////////
  375. int CAnswerFileEntry::GetParameterCount( void )
  376. {
  377. return ( m_xParameterCount );
  378. }
  379. /////////////////////////////////////////////////////////////////////////////
  380. //++
  381. //
  382. // SetNextEntryPointer
  383. //
  384. // Routine Description:
  385. // This function sets the m_pNextEntry member of a CAnswerFileEntry object.
  386. //
  387. // Arguments:
  388. // pAnswerFileEntry - points to a CAnswerFileEntry object.
  389. //
  390. // Return Value:
  391. // TRUE - indicates success
  392. // FALSE - indicates that an error occured
  393. //
  394. //--
  395. /////////////////////////////////////////////////////////////////////////////
  396. BOOL CAnswerFileEntry::SetNextEntryPointer( CAnswerFileEntry * pEntry )
  397. {
  398. BOOL fReturnValue;
  399. // If the next entry pointer has already been set free it. It will be set below.
  400. if ( m_pNextEntry != NULL )
  401. {
  402. delete m_pNextEntry;
  403. }
  404. // Set the next entry pointer.
  405. m_pNextEntry = pEntry;
  406. fReturnValue = TRUE;
  407. return ( fReturnValue );
  408. }
  409. /////////////////////////////////////////////////////////////////////////////
  410. //++
  411. //
  412. // GetNextEntryPointer
  413. //
  414. // Routine Description:
  415. // This function returns the m_pNextEntry member of a CAnswerFileEntry object.
  416. //
  417. // Arguments:
  418. // None
  419. //
  420. // Return Value:
  421. // The m_pNextEntry member of a CAnswerFileEntry object.
  422. //
  423. //--
  424. /////////////////////////////////////////////////////////////////////////////
  425. CAnswerFileEntry * CAnswerFileEntry::GetNextEntryPointer( void )
  426. {
  427. return ( m_pNextEntry );
  428. }
  429. /////////////////////////////////////////////////////////////////////////////
  430. //++
  431. //
  432. // ReadParameters
  433. //
  434. // Routine Description:
  435. // This function reads the parameters for an entry in the answer file.
  436. // It may create and initialize a CParameterListEntry object.
  437. //
  438. // Arguments:
  439. // pAnswerFileEntry - points to the CAnswerFileEntry object
  440. // pAnswerFileContext - points to the INFCONTEXT structure for the answer file
  441. //
  442. // Return Value:
  443. // TRUE - indicates that the parameters were read successfully
  444. // FALSE - indicates that an error occured
  445. //
  446. //--
  447. /////////////////////////////////////////////////////////////////////////////
  448. BOOL CAnswerFileEntry::ReadParameters( PINFCONTEXT pAnswerFileContext )
  449. {
  450. BOOL fReturnValue;
  451. // Are the parameters meaningfull?
  452. if ( pAnswerFileContext != NULL )
  453. {
  454. DWORD dwFieldCount;
  455. // How many fields are in the entry? There must be at least one to be meaningfull.
  456. dwFieldCount = SetupGetFieldCount( pAnswerFileContext );
  457. if ( dwFieldCount >= 1 )
  458. {
  459. // Read the parameters. Apparently SetupGetStringField does not handle
  460. // empty fields gracefully. So, any empty parameter shall be treated
  461. // as an error. Parsing will terminate at that point.
  462. TCHAR tszBuffer[MAX_INF_STRING_LENGTH]; // buffer to receive strings
  463. // Attempt to read the first parameter.
  464. fReturnValue = SetupGetStringField( pAnswerFileContext,
  465. 1,
  466. tszBuffer,
  467. MAX_INF_STRING_LENGTH,
  468. NULL );
  469. // Was the first parameter read?
  470. if ( fReturnValue == TRUE )
  471. {
  472. // Is the parameter string non-empty?
  473. if ( _tcslen( tszBuffer ) > 0 )
  474. {
  475. // Create a CParameterListEntry object and save its' address.
  476. CParameterListEntry * pParameterListEntry; // working pointer
  477. pParameterListEntry = new CParameterListEntry;
  478. if ( pParameterListEntry != NULL )
  479. {
  480. SetParameterListPointer( pParameterListEntry );
  481. // Initialize the first parameter string.
  482. pParameterListEntry->SetParameterString( tszBuffer );
  483. int xParameterCount = 1; // one parameter has already been read.
  484. // Are there additional parameters?
  485. if ( dwFieldCount >= 2 )
  486. {
  487. // Read the second and subsequent parameters.
  488. int xIndex;
  489. // On entry to this loop pParameterListEntry points to the first
  490. // CParameterListEntry object.
  491. for ( xIndex = 2; xIndex <= (int) dwFieldCount; xIndex++ )
  492. {
  493. // Attempt to read a parameter.
  494. fReturnValue = SetupGetStringField( pAnswerFileContext,
  495. xIndex,
  496. tszBuffer,
  497. MAX_INF_STRING_LENGTH,
  498. NULL );
  499. // Was a parameter read?
  500. if ( fReturnValue == TRUE )
  501. {
  502. // Is the parameter string non-empty?
  503. if ( _tcslen( tszBuffer ) > 0 )
  504. {
  505. // Create a CParameterListEntry object and save its' address.
  506. pParameterListEntry->SetNextParameterPointer( new CParameterListEntry );
  507. // Point to the newly created CParameterListEntry object.
  508. pParameterListEntry = pParameterListEntry->GetParameterListPointer();
  509. // Initialize the parameter string.
  510. pParameterListEntry->SetParameterString( tszBuffer );
  511. // Increment the count of parameters.
  512. xParameterCount += 1;
  513. } // if - parameter non-empty?
  514. else
  515. {
  516. // Since the parameter is an empty string, terminate
  517. // the loop.
  518. break;
  519. } // if - parameter non-empty?
  520. } // if - SetupGetStringField succeeded?
  521. else
  522. {
  523. // Since SetupGetStringField failed, terminate the loop.
  524. // fReturnValue will indicate error.
  525. break;
  526. } // if - SetupGetStringField succeeded?
  527. } // for loop reading 2nd and subsequent parameters
  528. } // Additional parameters?
  529. else
  530. {
  531. fReturnValue = TRUE;
  532. } // Additional parameters?
  533. // Set the parameter count.
  534. SetParameterCount( xParameterCount );
  535. } // if - memory allocation succeeded
  536. else
  537. {
  538. fReturnValue = FALSE;
  539. } // else - memory allocation failed.
  540. } // if - first parameter non-empty?
  541. else
  542. {
  543. // There is no use attempting to read additional parameters.
  544. SetParameterCount( 0 );
  545. } // if - first parameter non-empty?
  546. } // Was a parameter read?
  547. else
  548. {
  549. // There is no use attempting to read additional parameters.
  550. SetParameterCount( 0 );
  551. } // Was a parameter read?
  552. } // two or more fields?
  553. else
  554. {
  555. // It is legal for an entry to have no parameters, but not useful.
  556. SetParameterCount( 0 );
  557. fReturnValue = TRUE;
  558. } // two or more fields?
  559. }
  560. else
  561. {
  562. fReturnValue = FALSE;
  563. }
  564. return ( fReturnValue );
  565. }
  566. /////////////////////////////////////////////////////////////////////////////
  567. //++
  568. //
  569. // SetParameterListPointer
  570. //
  571. // Routine Description:
  572. // This function sets the m_pParameterList member of a CAnswerFileEntry object.
  573. //
  574. // Arguments:
  575. // pParameterList - points to a CParameterListEntry object.
  576. //
  577. // Return Value:
  578. // TRUE - indicates success
  579. // FALSE - indicates that an error occured.
  580. //
  581. //--
  582. /////////////////////////////////////////////////////////////////////////////
  583. BOOL CAnswerFileEntry::SetParameterListPointer( CParameterListEntry * pParameterList )
  584. {
  585. BOOL fReturnValue;
  586. // If the parameter list pointer has already been set free it. It will be set below.
  587. if ( m_pParameterList != NULL )
  588. {
  589. delete m_pParameterList;
  590. }
  591. // Set the next entry pointer.
  592. m_pParameterList = pParameterList;
  593. fReturnValue = TRUE;
  594. return ( fReturnValue );
  595. }
  596. /////////////////////////////////////////////////////////////////////////////
  597. //++
  598. //
  599. // GetParameterListPointer
  600. //
  601. // Routine Description:
  602. // This function returns the m_pParameterList data member of a CAnswerFileEntry object.
  603. //
  604. // Arguments:
  605. // None
  606. //
  607. // Return Value:
  608. // The value of the m_pParameterList data member of a CAnswerFileEntry object.
  609. //
  610. //--
  611. /////////////////////////////////////////////////////////////////////////////
  612. CParameterListEntry * CAnswerFileEntry::GetParameterListPointer( void )
  613. {
  614. return ( m_pParameterList );
  615. }
  616. // The following set of functions implements the CAnswerFileSection class.
  617. /////////////////////////////////////////////////////////////////////////////
  618. //++
  619. //
  620. // CAnswerFileSection
  621. //
  622. // Routine Description:
  623. // This is the constructor for the CAnswerFileSection class.
  624. //
  625. // Arguments:
  626. // None
  627. //
  628. // Return Value:
  629. // None
  630. //
  631. //--
  632. /////////////////////////////////////////////////////////////////////////////
  633. CAnswerFileSection::CAnswerFileSection()
  634. {
  635. // Initialize the pointer to the CAnswerFileEntry objects to NULL.
  636. m_pEntries = NULL; // The CAnswerFileEntry object that this data member
  637. // points to will be allocated with the new operator.
  638. }
  639. /////////////////////////////////////////////////////////////////////////////
  640. //++
  641. //
  642. // GetEntryPointer
  643. //
  644. // Routine Description:
  645. // This function returns the contents of the m_pEntries member of a
  646. // CAnswerFileSection object.
  647. //
  648. // Arguments:
  649. // None
  650. //
  651. // Return Value:
  652. // A pointer to a CAnswerFileEntry object.
  653. //
  654. //--
  655. /////////////////////////////////////////////////////////////////////////////
  656. CAnswerFileEntry * CAnswerFileSection::GetEntryPointer( void )
  657. {
  658. return ( m_pEntries );
  659. }
  660. /////////////////////////////////////////////////////////////////////////////
  661. //++
  662. //
  663. // ~CAnswerFileSection
  664. //
  665. // Routine Description:
  666. // This is the destructor for the CAnswerFileSection class.
  667. //
  668. // Arguments:
  669. // None
  670. //
  671. // Return Value:
  672. // None
  673. //
  674. //--
  675. /////////////////////////////////////////////////////////////////////////////
  676. CAnswerFileSection::~CAnswerFileSection()
  677. {
  678. // Delete the CAnswerFileEntry objects.
  679. if ( m_pEntries != NULL )
  680. {
  681. delete m_pEntries;
  682. }
  683. }
  684. /////////////////////////////////////////////////////////////////////////////
  685. //++
  686. //
  687. // ReadAnswerFileSection
  688. //
  689. // Routine Description:
  690. // This function reads the entries in an answer file.
  691. //
  692. // Arguments:
  693. // hAnswerFile - the handle to the answer file
  694. // ptszSection - points to the answer file section name
  695. //
  696. //
  697. // Return Value:
  698. // TRUE - indicates that the section whose name is in ptszSection was read
  699. // from the answer file whose handle is hAnswerFile successfully.
  700. // FALSE - indicates that an error occured.
  701. //
  702. //--
  703. /////////////////////////////////////////////////////////////////////////////
  704. BOOL CAnswerFileSection::ReadAnswerFileSection( HINF hAnswerFile,
  705. LPTSTR ptszSection )
  706. {
  707. BOOL fReturnValue;
  708. // Is the desired section present and non-empty in the answer file?
  709. LONG lSectionLineCount;
  710. lSectionLineCount = SetupGetLineCount( hAnswerFile, ptszSection );
  711. if ( lSectionLineCount > 0L )
  712. {
  713. // The section is present and non empty. Find the first entry.
  714. INFCONTEXT AnswerFileContext;
  715. fReturnValue = SetupFindFirstLine( hAnswerFile,
  716. ptszSection,
  717. NULL, // find first line of the section
  718. &AnswerFileContext );
  719. // Was the first entry found?
  720. if ( fReturnValue == TRUE )
  721. {
  722. // Get the key for the first entry.
  723. TCHAR tszBuffer[MAX_INF_STRING_LENGTH]; // buffer to receive strings
  724. fReturnValue = SetupGetStringField( &AnswerFileContext,
  725. 0, // get the key
  726. tszBuffer,
  727. MAX_INF_STRING_LENGTH,
  728. NULL );
  729. // Was the first key read?
  730. if ( fReturnValue == TRUE )
  731. {
  732. // The key for the first entry in the section was read.
  733. // Create the first CAnswerFileEntry object and save its' address.
  734. m_pEntries = new CAnswerFileEntry; // m_pEntries points to the head of
  735. // the list of CAnswerFileEntry objects.
  736. if ( m_pEntries == NULL )
  737. {
  738. fReturnValue = FALSE;
  739. }
  740. else
  741. {
  742. // Set the key for the first CAnswerFileEntry object.
  743. fReturnValue = m_pEntries->SetKey( tszBuffer );
  744. }
  745. // Was the key for the first entry set?
  746. if ( fReturnValue == TRUE )
  747. {
  748. // Read the parameters for the first entry.
  749. fReturnValue = m_pEntries->ReadParameters( &AnswerFileContext );
  750. // Were the parameters for the first entry read successfully?
  751. if ( fReturnValue == TRUE )
  752. {
  753. CAnswerFileEntry * pEntry; // working pointer to entries
  754. // Initialize the working pointer to the head of the list.
  755. pEntry = m_pEntries;
  756. // Read the rest of the entries/
  757. while ( (SetupFindNextLine( &AnswerFileContext, &AnswerFileContext ) == TRUE) &&
  758. (fReturnValue == TRUE) )
  759. {
  760. // Create a CAnswerFileEntry object for the next entry.
  761. pEntry->SetNextEntryPointer( new CAnswerFileEntry );
  762. // Operate on the next entry object.
  763. pEntry = pEntry->GetNextEntryPointer();
  764. if ( pEntry == FALSE )
  765. {
  766. fReturnValue = FALSE;
  767. break;
  768. }
  769. // Read the key for this entry.
  770. fReturnValue = SetupGetStringField( &AnswerFileContext,
  771. 0, // get the key
  772. tszBuffer,
  773. MAX_INF_STRING_LENGTH,
  774. NULL );
  775. // Was the key for this entry read?
  776. if ( fReturnValue == TRUE )
  777. {
  778. pEntry->SetKey( tszBuffer );
  779. // Read the parameters for the next entry.
  780. fReturnValue = pEntry->ReadParameters( &AnswerFileContext );
  781. }
  782. } // while reading lines in the section
  783. } // params for first entry read successfully?
  784. } // Was the first key set?
  785. } // Was the first key read?
  786. } // Was the first entry found?
  787. }
  788. else
  789. {
  790. // Either the section does not exist or it is empty.
  791. fReturnValue = FALSE;
  792. } // Does a non-empty section exist?
  793. return ( fReturnValue );
  794. }