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.

1981 lines
46 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. alinf.c
  5. Abstract:
  6. This module implements functions to access the parsed INF.
  7. Author:
  8. Sunil Pai (sunilp) 13-Nov-1991
  9. Revision History:
  10. Calin Negreanu (calinn) 03-Sep-1998 - Major parser rewrite to work with a swap file
  11. --*/
  12. #include "winnt.h"
  13. #include <string.h>
  14. #include <ctype.h>
  15. #include <errno.h>
  16. #include <dos.h>
  17. #include <stdio.h>
  18. #include <io.h>
  19. #include <fcntl.h>
  20. #include <sys/types.h>
  21. #include <sys/stat.h>
  22. #define MAX_BUFFER_SIZE 0x1680 //7D00
  23. #define SWAP_SIGNATURE 0xAABBCCDD
  24. #define SWAP_SIGN_SIZE 4
  25. #define NULL_HANDLE 0
  26. #define MAX_PATH 256
  27. //
  28. // typedefs exported
  29. //
  30. typedef unsigned *PUNSIGNED;
  31. typedef PVOID SECTION_HANDLE;
  32. typedef unsigned long LINE_HANDLE;
  33. typedef unsigned long VALUE_HANDLE;
  34. typedef struct _SWAP_VALUE {
  35. unsigned ValueSize;
  36. VALUE_HANDLE NextValue;
  37. char ValueName[];
  38. } SWAP_VALUE, *PSWAP_VALUE;
  39. typedef struct _SWAP_LINE {
  40. unsigned LineSize;
  41. LINE_HANDLE NextLine;
  42. VALUE_HANDLE FirstValue;
  43. VALUE_HANDLE LastValue;
  44. char LineName[];
  45. } SWAP_LINE, *PSWAP_LINE;
  46. typedef struct _SWAP_SECTION {
  47. unsigned SectionSize;
  48. SECTION_HANDLE NextSection;
  49. LINE_HANDLE FirstLine;
  50. LINE_HANDLE LastLine;
  51. char SectionName[];
  52. } SWAP_SECTION, *PSWAP_SECTION;
  53. typedef struct _SWAP_INF {
  54. SECTION_HANDLE CurrentSection;
  55. SECTION_HANDLE FirstSection;
  56. SECTION_HANDLE LastSection;
  57. int SwapFileHandle;
  58. unsigned long BufferSize;
  59. BOOLEAN BufferDirty;
  60. PCHAR Buffer;
  61. unsigned long BufferStart;
  62. unsigned long BufferEnd;
  63. SECTION_HANDLE LastSectionHandle;
  64. unsigned LastLineIndex;
  65. LINE_HANDLE LastLineHandle;
  66. unsigned LastValueIndex;
  67. VALUE_HANDLE LastValueHandle;
  68. char SwapFile[];
  69. } SWAP_INF, *PSWAP_INF;
  70. char *CommonStrings[] =
  71. { (char *)("d1")
  72. };
  73. //
  74. // DEFINES USED FOR THE PARSER INTERNALLY
  75. //
  76. //
  77. // typedefs used
  78. //
  79. typedef enum _tokentype {
  80. TOK_EOF,
  81. TOK_EOL,
  82. TOK_LBRACE,
  83. TOK_RBRACE,
  84. TOK_STRING,
  85. TOK_EQUAL,
  86. TOK_COMMA,
  87. TOK_ERRPARSE,
  88. TOK_ERRNOMEM
  89. } TOKENTYPE, *PTOKENTTYPE;
  90. typedef struct _token {
  91. TOKENTYPE Type;
  92. PCHAR pValue;
  93. } TOKEN, *PTOKEN;
  94. //
  95. // Routine defines
  96. //
  97. PSWAP_SECTION
  98. GetSectionPtr (
  99. IN PSWAP_INF InfHandle,
  100. IN SECTION_HANDLE SectionHandle
  101. );
  102. PSWAP_LINE
  103. GetLinePtr (
  104. IN PSWAP_INF InfHandle,
  105. IN LINE_HANDLE LineHandle
  106. );
  107. PSWAP_VALUE
  108. GetValuePtr (
  109. IN PSWAP_INF InfHandle,
  110. IN VALUE_HANDLE ValueHandle
  111. );
  112. SECTION_HANDLE
  113. GetNextSection (
  114. IN PSWAP_INF InfHandle,
  115. IN SECTION_HANDLE SectionHandle
  116. );
  117. LINE_HANDLE
  118. GetNextLine (
  119. IN PSWAP_INF InfHandle,
  120. IN LINE_HANDLE LineHandle
  121. );
  122. VALUE_HANDLE
  123. GetNextValue (
  124. IN PSWAP_INF InfHandle,
  125. IN VALUE_HANDLE ValueHandle
  126. );
  127. SECTION_HANDLE
  128. AddSection (
  129. IN PSWAP_INF InfHandle,
  130. IN PCHAR SectionName
  131. );
  132. LINE_HANDLE
  133. AddLine (
  134. IN PSWAP_INF InfHandle,
  135. IN SECTION_HANDLE Section,
  136. IN PCHAR LineName
  137. );
  138. VALUE_HANDLE
  139. AddValue (
  140. IN PSWAP_INF InfHandle,
  141. IN LINE_HANDLE Line,
  142. IN PCHAR ValueName
  143. );
  144. SECTION_HANDLE
  145. StoreNewSection (
  146. IN PSWAP_INF InfHandle,
  147. IN PSWAP_SECTION Section
  148. );
  149. LINE_HANDLE
  150. StoreNewLine (
  151. IN PSWAP_INF InfHandle,
  152. IN SECTION_HANDLE Section,
  153. IN PSWAP_LINE Line
  154. );
  155. VALUE_HANDLE
  156. StoreNewValue (
  157. IN PSWAP_INF InfHandle,
  158. IN LINE_HANDLE Line,
  159. IN PSWAP_VALUE Value
  160. );
  161. BOOLEAN
  162. LoadBuffer (
  163. IN PSWAP_INF InfHandle,
  164. IN unsigned long Offset
  165. );
  166. TOKEN
  167. GetToken (
  168. IN FILE *File
  169. );
  170. BOOLEAN
  171. ParseInfBuffer (
  172. IN PSWAP_INF InfHandle,
  173. IN FILE *File,
  174. IN OUT unsigned *LineNumber
  175. );
  176. //
  177. // Internal Routine declarations for searching in the INF structures
  178. //
  179. VALUE_HANDLE
  180. SearchValueInLineByIndex (
  181. IN PSWAP_INF InfHandle,
  182. IN LINE_HANDLE Line,
  183. IN unsigned ValueIndex
  184. );
  185. LINE_HANDLE
  186. SearchLineInSectionByName (
  187. IN PSWAP_INF InfHandle,
  188. IN SECTION_HANDLE Section,
  189. IN PCHAR LineName
  190. );
  191. LINE_HANDLE
  192. SearchLineInSectionByIndex (
  193. IN PSWAP_INF InfHandle,
  194. IN SECTION_HANDLE Section,
  195. IN unsigned LineIndex
  196. );
  197. SECTION_HANDLE
  198. SearchSectionByName (
  199. IN PSWAP_INF InfHandle,
  200. IN PCHAR SectionName
  201. );
  202. //
  203. // ROUTINE DEFINITIONS
  204. //
  205. static unsigned g_Sequencer = 0;
  206. //
  207. // returns a handle to use for further inf parsing
  208. //
  209. int
  210. DnInitINFBuffer (
  211. IN FILE *InfFileHandle,
  212. OUT PVOID *pINFHandle,
  213. OUT unsigned *LineNumber
  214. )
  215. /*++
  216. Routine Description:
  217. Arguments:
  218. Return Value:
  219. --*/
  220. {
  221. char SwapFilePath[MAX_PATH];
  222. PSWAP_INF InfHandle = NULL;
  223. int Status;
  224. unsigned long SwapSign;
  225. *LineNumber = 0;
  226. //
  227. // Prepare the swap file path
  228. //
  229. sprintf (SwapFilePath, "%c:\\INF%03u.SWP", DngSwapDriveLetter, g_Sequencer++);
  230. //
  231. // Allocate and populate the SWAP_INF structure
  232. //
  233. InfHandle = MALLOC(sizeof(SWAP_INF) + strlen (SwapFilePath) + 1, TRUE);
  234. InfHandle->CurrentSection = NULL;
  235. InfHandle->FirstSection = NULL;
  236. InfHandle->LastSection = NULL;
  237. InfHandle->SwapFileHandle = -1;
  238. InfHandle->BufferSize = 0;
  239. InfHandle->BufferDirty = FALSE;
  240. InfHandle->Buffer = NULL;
  241. InfHandle->BufferStart = 0;
  242. InfHandle->BufferEnd = 0;
  243. InfHandle->LastSectionHandle = NULL_HANDLE;
  244. InfHandle->LastLineIndex = 0xffff;
  245. InfHandle->LastLineHandle = NULL_HANDLE;
  246. InfHandle->LastValueIndex = 0xffff;
  247. InfHandle->LastValueHandle = NULL_HANDLE;
  248. strcpy (InfHandle->SwapFile, SwapFilePath);
  249. //
  250. // Prepare the swap file
  251. //
  252. InfHandle->SwapFileHandle = open (InfHandle->SwapFile, O_BINARY|O_CREAT|O_TRUNC|O_RDWR, S_IREAD|S_IWRITE);
  253. if (InfHandle->SwapFileHandle == -1) {
  254. FREE (InfHandle);
  255. Status = errno;
  256. }
  257. else {
  258. //
  259. // write down signature
  260. //
  261. SwapSign = SWAP_SIGNATURE;
  262. write (InfHandle->SwapFileHandle, &SwapSign, SWAP_SIGN_SIZE);
  263. //
  264. // Prepare the buffer
  265. //
  266. InfHandle->BufferSize = MAX_BUFFER_SIZE;
  267. InfHandle->Buffer = MALLOC (MAX_BUFFER_SIZE, TRUE);
  268. InfHandle->BufferStart = SWAP_SIGN_SIZE;
  269. InfHandle->BufferEnd = SWAP_SIGN_SIZE;
  270. //
  271. // Parse the file
  272. //
  273. if (!ParseInfBuffer (InfHandle, InfFileHandle, LineNumber)) {
  274. //
  275. // Free SWAP_INF structure
  276. //
  277. DnFreeINFBuffer (InfHandle);
  278. *pINFHandle = NULL;
  279. Status = EBADF;
  280. } else {
  281. *pINFHandle = InfHandle;
  282. Status = EZERO;
  283. }
  284. }
  285. //
  286. // Clean up and return
  287. //
  288. return(Status);
  289. }
  290. //
  291. // frees an INF Buffer
  292. //
  293. int
  294. DnFreeINFBuffer (
  295. IN PVOID INFHandle
  296. )
  297. /*++
  298. Routine Description:
  299. Arguments:
  300. Return Value:
  301. --*/
  302. {
  303. PSWAP_INF pINF;
  304. PSWAP_SECTION Section;
  305. SECTION_HANDLE SectionHandle;
  306. //
  307. // Valid INF Handle?
  308. //
  309. if (INFHandle == (PVOID)NULL) {
  310. return EZERO;
  311. }
  312. //
  313. // cast the buffer into an INF structure
  314. //
  315. pINF = (PSWAP_INF)INFHandle;
  316. //
  317. // Close and delete the swap file
  318. //
  319. close (pINF->SwapFileHandle);
  320. remove (pINF->SwapFile);
  321. //
  322. // free temporary buffer
  323. //
  324. FREE (pINF->Buffer);
  325. //
  326. // Free section list
  327. //
  328. SectionHandle = pINF->FirstSection;
  329. while (SectionHandle) {
  330. Section = GetSectionPtr (pINF, SectionHandle);
  331. SectionHandle = Section->NextSection;
  332. FREE (Section);
  333. }
  334. //
  335. // free the inf structure too
  336. //
  337. FREE(pINF);
  338. return( EZERO );
  339. }
  340. SECTION_HANDLE
  341. AddSection (
  342. IN PSWAP_INF InfHandle,
  343. IN PCHAR SectionName
  344. )
  345. {
  346. SECTION_HANDLE SectionHandle;
  347. PSWAP_SECTION Section;
  348. unsigned SectionSize;
  349. //
  350. // Let's walk through the section structures to make sure that this section does
  351. // not exist.
  352. //
  353. SectionHandle = InfHandle->FirstSection;
  354. while (SectionHandle) {
  355. Section = GetSectionPtr (InfHandle, SectionHandle);
  356. if (stricmp (Section->SectionName, SectionName) == 0) {
  357. break;
  358. }
  359. SectionHandle = GetNextSection (InfHandle, SectionHandle);
  360. }
  361. if (!SectionHandle) {
  362. //
  363. // Allocate the section structure
  364. //
  365. SectionSize = sizeof(SWAP_SECTION) + (SectionName?strlen (SectionName):0) + 1;
  366. Section = MALLOC (SectionSize, TRUE);
  367. Section->SectionSize = SectionSize;
  368. Section->NextSection = NULL;
  369. Section->FirstLine = NULL_HANDLE;
  370. Section->LastLine = NULL_HANDLE;
  371. if (SectionName) {
  372. strcpy (Section->SectionName, SectionName);
  373. }
  374. else {
  375. Section->SectionName[0] = 0;
  376. }
  377. //
  378. // Store the newly created section
  379. //
  380. SectionHandle = StoreNewSection (InfHandle, Section);
  381. }
  382. return SectionHandle;
  383. }
  384. LINE_HANDLE
  385. AddLine (
  386. IN PSWAP_INF InfHandle,
  387. IN SECTION_HANDLE Section,
  388. IN PCHAR LineName
  389. )
  390. {
  391. LINE_HANDLE LineHandle;
  392. PSWAP_LINE Line;
  393. unsigned LineSize;
  394. //
  395. // Allocate the line structure
  396. //
  397. LineSize = sizeof(SWAP_LINE) + (LineName?strlen (LineName):0) + 1;
  398. Line = MALLOC (LineSize, TRUE);
  399. Line->LineSize = LineSize;
  400. Line->NextLine = NULL_HANDLE;
  401. Line->FirstValue = NULL_HANDLE;
  402. Line->LastValue = NULL_HANDLE;
  403. if (LineName) {
  404. strcpy (Line->LineName, LineName);
  405. }
  406. else {
  407. Line->LineName[0] = 0;
  408. }
  409. //
  410. // Store the newly created line
  411. //
  412. LineHandle = StoreNewLine (InfHandle, Section, Line);
  413. FREE (Line);
  414. return LineHandle;
  415. }
  416. VALUE_HANDLE
  417. AddValue (
  418. IN PSWAP_INF InfHandle,
  419. IN LINE_HANDLE Line,
  420. IN PCHAR ValueName
  421. )
  422. {
  423. VALUE_HANDLE ValueHandle;
  424. PSWAP_VALUE Value;
  425. unsigned ValueSize;
  426. //
  427. // Allocate the value structure
  428. //
  429. ValueSize = sizeof(SWAP_VALUE) + (ValueName?strlen (ValueName):0) + 1;
  430. Value = MALLOC (ValueSize, TRUE);
  431. Value->ValueSize = ValueSize;
  432. Value->NextValue = NULL_HANDLE;
  433. if (ValueName) {
  434. strcpy (Value->ValueName, ValueName);
  435. }
  436. else {
  437. Value->ValueName[0] = 0;
  438. }
  439. //
  440. // Store the newly created line
  441. //
  442. ValueHandle = StoreNewValue (InfHandle, Line, Value);
  443. FREE (Value);
  444. return ValueHandle;
  445. }
  446. PSWAP_SECTION
  447. GetSectionPtr (
  448. IN PSWAP_INF InfHandle,
  449. IN SECTION_HANDLE SectionHandle
  450. )
  451. {
  452. return (PSWAP_SECTION) SectionHandle;
  453. }
  454. PSWAP_LINE
  455. GetLinePtr (
  456. IN PSWAP_INF InfHandle,
  457. IN LINE_HANDLE LineHandle
  458. )
  459. {
  460. //
  461. // Verify if the buffer contains the requested line (at least the size of LineSize)
  462. //
  463. if ((InfHandle->BufferStart > LineHandle) ||
  464. (InfHandle->BufferEnd < (LineHandle + sizeof (unsigned))) ||
  465. (InfHandle->BufferEnd < (LineHandle + *((PUNSIGNED)(InfHandle->Buffer+LineHandle-InfHandle->BufferStart))))
  466. ) {
  467. LoadBuffer (InfHandle, LineHandle);
  468. }
  469. return (PSWAP_LINE) (InfHandle->Buffer+LineHandle-InfHandle->BufferStart);
  470. }
  471. PSWAP_VALUE
  472. GetValuePtr (
  473. IN PSWAP_INF InfHandle,
  474. IN VALUE_HANDLE ValueHandle
  475. )
  476. {
  477. //
  478. // Verify if the buffer contains the requested value (at least the size of ValueSize)
  479. //
  480. if ((InfHandle->BufferStart > ValueHandle) ||
  481. (InfHandle->BufferEnd < (ValueHandle + sizeof (unsigned))) ||
  482. (InfHandle->BufferEnd < (ValueHandle + *((PUNSIGNED)(InfHandle->Buffer+ValueHandle-InfHandle->BufferStart))))
  483. ) {
  484. LoadBuffer (InfHandle, ValueHandle);
  485. }
  486. return (PSWAP_VALUE) (InfHandle->Buffer+ValueHandle-InfHandle->BufferStart);
  487. }
  488. SECTION_HANDLE
  489. GetNextSection (
  490. IN PSWAP_INF InfHandle,
  491. IN SECTION_HANDLE SectionHandle
  492. )
  493. {
  494. PSWAP_SECTION Section;
  495. Section = GetSectionPtr (InfHandle, SectionHandle);
  496. return Section->NextSection;
  497. }
  498. LINE_HANDLE
  499. GetNextLine (
  500. IN PSWAP_INF InfHandle,
  501. IN LINE_HANDLE LineHandle
  502. )
  503. {
  504. PSWAP_LINE Line;
  505. Line = GetLinePtr (InfHandle, LineHandle);
  506. return Line->NextLine;
  507. }
  508. VALUE_HANDLE
  509. GetNextValue (
  510. IN PSWAP_INF InfHandle,
  511. IN VALUE_HANDLE ValueHandle
  512. )
  513. {
  514. PSWAP_VALUE Value;
  515. Value = GetValuePtr (InfHandle, ValueHandle);
  516. return Value->NextValue;
  517. }
  518. SECTION_HANDLE
  519. StoreNewSection (
  520. IN PSWAP_INF InfHandle,
  521. IN PSWAP_SECTION Section
  522. )
  523. {
  524. PSWAP_SECTION LastSectionPtr;
  525. if (!InfHandle->FirstSection) {
  526. InfHandle->FirstSection = (SECTION_HANDLE) Section;
  527. InfHandle->LastSection = (SECTION_HANDLE) Section;
  528. }
  529. else {
  530. LastSectionPtr = GetSectionPtr (InfHandle, InfHandle->LastSection);
  531. LastSectionPtr->NextSection = (SECTION_HANDLE) Section;
  532. InfHandle->LastSection = (SECTION_HANDLE) Section;
  533. }
  534. return (SECTION_HANDLE) Section;
  535. }
  536. LINE_HANDLE
  537. StoreNewLine (
  538. IN PSWAP_INF InfHandle,
  539. IN SECTION_HANDLE Section,
  540. IN PSWAP_LINE Line
  541. )
  542. {
  543. PSWAP_SECTION SectionPtr;
  544. LINE_HANDLE LineHandle;
  545. PSWAP_LINE LastLinePtr;
  546. //
  547. // Let's store data in the swap file
  548. //
  549. if ((InfHandle->BufferSize-InfHandle->BufferEnd+InfHandle->BufferStart) < Line->LineSize) {
  550. LoadBuffer (InfHandle, 0);
  551. }
  552. memcpy (InfHandle->Buffer+InfHandle->BufferEnd-InfHandle->BufferStart, Line, Line->LineSize);
  553. InfHandle->BufferDirty = TRUE;
  554. LineHandle = InfHandle->BufferEnd;
  555. InfHandle->BufferEnd += Line->LineSize;
  556. SectionPtr = GetSectionPtr (InfHandle, Section);
  557. if (!SectionPtr->LastLine) {
  558. SectionPtr->FirstLine = LineHandle;
  559. SectionPtr->LastLine = LineHandle;
  560. }
  561. else {
  562. LastLinePtr = GetLinePtr (InfHandle, SectionPtr->LastLine);
  563. LastLinePtr->NextLine = LineHandle;
  564. InfHandle->BufferDirty = TRUE;
  565. SectionPtr = GetSectionPtr (InfHandle, Section);
  566. SectionPtr->LastLine = LineHandle;
  567. }
  568. return LineHandle;
  569. }
  570. VALUE_HANDLE
  571. StoreNewValue (
  572. IN PSWAP_INF InfHandle,
  573. IN LINE_HANDLE Line,
  574. IN PSWAP_VALUE Value
  575. )
  576. {
  577. PSWAP_LINE LinePtr;
  578. VALUE_HANDLE ValueHandle;
  579. PSWAP_VALUE LastValuePtr;
  580. //
  581. // Let's store data in the swap file
  582. //
  583. if ((InfHandle->BufferSize-InfHandle->BufferEnd+InfHandle->BufferStart) < Value->ValueSize) {
  584. LoadBuffer (InfHandle, 0);
  585. }
  586. memcpy (InfHandle->Buffer+InfHandle->BufferEnd-InfHandle->BufferStart, Value, Value->ValueSize);
  587. InfHandle->BufferDirty = TRUE;
  588. ValueHandle = InfHandle->BufferEnd;
  589. InfHandle->BufferEnd += Value->ValueSize;
  590. LinePtr = GetLinePtr (InfHandle, Line);
  591. if (!LinePtr->LastValue) {
  592. LinePtr->FirstValue = ValueHandle;
  593. LinePtr->LastValue = ValueHandle;
  594. InfHandle->BufferDirty = TRUE;
  595. }
  596. else {
  597. LastValuePtr = GetValuePtr (InfHandle, LinePtr->LastValue);
  598. LastValuePtr->NextValue = ValueHandle;
  599. InfHandle->BufferDirty = TRUE;
  600. LinePtr = GetLinePtr (InfHandle, Line);
  601. LinePtr->LastValue = ValueHandle;
  602. InfHandle->BufferDirty = TRUE;
  603. }
  604. return ValueHandle;
  605. }
  606. BOOLEAN
  607. LoadBuffer (
  608. IN PSWAP_INF InfHandle,
  609. IN unsigned long Offset
  610. )
  611. {
  612. //
  613. // See if we need to write the buffer to disk (e.g. is dirty)
  614. //
  615. if (InfHandle->BufferDirty) {
  616. lseek (InfHandle->SwapFileHandle, InfHandle->BufferStart, SEEK_SET);
  617. write (InfHandle->SwapFileHandle, InfHandle->Buffer, (unsigned int) (InfHandle->BufferEnd-InfHandle->BufferStart));
  618. }
  619. if (!Offset) {
  620. Offset = lseek (InfHandle->SwapFileHandle, 0, SEEK_END);
  621. }
  622. InfHandle->BufferStart = lseek (InfHandle->SwapFileHandle, Offset, SEEK_SET);
  623. InfHandle->BufferEnd = InfHandle->BufferStart + read (InfHandle->SwapFileHandle, InfHandle->Buffer, MAX_BUFFER_SIZE);
  624. return TRUE;
  625. }
  626. SECTION_HANDLE
  627. SearchSectionByName (
  628. IN PSWAP_INF InfHandle,
  629. IN PCHAR SectionName
  630. )
  631. {
  632. SECTION_HANDLE SectionHandle;
  633. PSWAP_SECTION Section;
  634. SectionHandle = InfHandle->FirstSection;
  635. while (SectionHandle) {
  636. Section = GetSectionPtr (InfHandle, SectionHandle);
  637. if (stricmp (Section->SectionName, SectionName?SectionName:"") == 0) {
  638. break;
  639. }
  640. SectionHandle = GetNextSection (InfHandle, SectionHandle);
  641. }
  642. if (SectionHandle != InfHandle->LastSectionHandle) {
  643. InfHandle->LastSectionHandle = SectionHandle;
  644. InfHandle->LastLineIndex = 0xffff;
  645. InfHandle->LastLineHandle = NULL_HANDLE;
  646. InfHandle->LastValueIndex = 0xffff;
  647. InfHandle->LastValueHandle = NULL_HANDLE;
  648. }
  649. return SectionHandle;
  650. }
  651. LINE_HANDLE
  652. SearchLineInSectionByName (
  653. IN PSWAP_INF InfHandle,
  654. IN SECTION_HANDLE Section,
  655. IN PCHAR LineName
  656. )
  657. {
  658. PSWAP_SECTION SectionPtr;
  659. LINE_HANDLE LineHandle;
  660. PSWAP_LINE Line;
  661. unsigned index;
  662. if (!Section) {
  663. return NULL_HANDLE;
  664. }
  665. SectionPtr = GetSectionPtr (InfHandle, Section);
  666. LineHandle = SectionPtr->FirstLine;
  667. index = 0;
  668. while (LineHandle) {
  669. Line = GetLinePtr (InfHandle, LineHandle);
  670. if (stricmp (Line->LineName, LineName?LineName:"") == 0) {
  671. break;
  672. }
  673. index ++;
  674. LineHandle = GetNextLine (InfHandle, LineHandle);
  675. }
  676. if (LineHandle != InfHandle->LastLineHandle) {
  677. InfHandle->LastLineIndex = index;
  678. InfHandle->LastLineHandle = LineHandle;
  679. InfHandle->LastValueIndex = 0xffff;
  680. InfHandle->LastValueHandle = NULL_HANDLE;
  681. }
  682. return LineHandle;
  683. }
  684. LINE_HANDLE
  685. SearchLineInSectionByIndex (
  686. IN PSWAP_INF InfHandle,
  687. IN SECTION_HANDLE Section,
  688. IN unsigned LineIndex
  689. )
  690. {
  691. PSWAP_SECTION SectionPtr;
  692. LINE_HANDLE LineHandle;
  693. unsigned index;
  694. if (!Section) {
  695. return NULL_HANDLE;
  696. }
  697. //
  698. // Optimize access
  699. //
  700. if ((InfHandle->LastSectionHandle == Section) &&
  701. (InfHandle->LastLineIndex <= LineIndex)
  702. ) {
  703. LineHandle = InfHandle->LastLineHandle;
  704. index = InfHandle->LastLineIndex;
  705. }
  706. else {
  707. SectionPtr = GetSectionPtr (InfHandle, Section);
  708. LineHandle = SectionPtr->FirstLine;
  709. index = 0;
  710. }
  711. while (LineHandle) {
  712. if (index == LineIndex) {
  713. break;
  714. }
  715. index ++;
  716. LineHandle = GetNextLine (InfHandle, LineHandle);
  717. }
  718. if (LineHandle != InfHandle->LastLineHandle) {
  719. InfHandle->LastLineIndex = LineIndex;
  720. InfHandle->LastLineHandle = LineHandle;
  721. InfHandle->LastValueIndex = 0xffff;
  722. InfHandle->LastValueHandle = NULL_HANDLE;
  723. }
  724. return LineHandle;
  725. }
  726. VALUE_HANDLE
  727. SearchValueInLineByIndex (
  728. IN PSWAP_INF InfHandle,
  729. IN LINE_HANDLE Line,
  730. IN unsigned ValueIndex
  731. )
  732. {
  733. PSWAP_LINE LinePtr;
  734. VALUE_HANDLE ValueHandle;
  735. unsigned index;
  736. if (!Line) {
  737. return NULL_HANDLE;
  738. }
  739. //
  740. // Optimize access
  741. //
  742. if ((InfHandle->LastLineHandle == Line) &&
  743. (InfHandle->LastValueIndex <= ValueIndex)
  744. ) {
  745. ValueHandle = InfHandle->LastValueHandle;
  746. index = InfHandle->LastValueIndex;
  747. }
  748. else {
  749. LinePtr = GetLinePtr (InfHandle, Line);
  750. ValueHandle = LinePtr->FirstValue;
  751. index = 0;
  752. }
  753. while (ValueHandle) {
  754. if (index == ValueIndex) {
  755. break;
  756. }
  757. index ++;
  758. ValueHandle = GetNextValue (InfHandle, ValueHandle);
  759. }
  760. InfHandle->LastValueIndex = ValueIndex;
  761. InfHandle->LastValueHandle = ValueHandle;
  762. return ValueHandle;
  763. }
  764. //
  765. // Globals used by the token parser
  766. //
  767. // string terminators are the whitespace characters (isspace: space, tab,
  768. // linefeed, formfeed, vertical tab, carriage return) or the chars given below
  769. CHAR StringTerminators[] = {'[', ']', '=', ',', '\"', ' ', '\t',
  770. '\n','\f','\v','\r','\032', 0};
  771. //
  772. // quoted string terminators allow some of the regular terminators to
  773. // appear as characters
  774. CHAR QStringTerminators[] = {'\"', '\n','\f','\v', '\r','\032', 0};
  775. //
  776. // Main parser routine
  777. //
  778. BOOLEAN
  779. ParseInfBuffer (
  780. IN PSWAP_INF InfHandle,
  781. IN FILE *File,
  782. IN OUT unsigned *LineNumber
  783. )
  784. /*++
  785. Routine Description:
  786. Given a character buffer containing the INF file, this routine parses
  787. the INF into an internal form with Section records, Line records and
  788. Value records.
  789. Arguments:
  790. InfHandle - PSWAP_INF structure used to create INF structures
  791. File - supplies open, rewound CRT handle to file.
  792. LineNumber - In case of error, this variable will contain the line
  793. in the file that contains a syntax error.
  794. Return Value:
  795. TRUE - the INF file was parsed successfully
  796. FALSE - otherwise
  797. --*/
  798. {
  799. PCHAR pchSectionName, pchValue;
  800. unsigned State, InfLine;
  801. TOKEN Token;
  802. BOOLEAN Done;
  803. BOOLEAN Error;
  804. int ErrorCode;
  805. SECTION_HANDLE LastSection = NULL;
  806. LINE_HANDLE LastLine = NULL_HANDLE;
  807. *LineNumber = 0;
  808. //
  809. // Set initial state
  810. //
  811. State = 1;
  812. InfLine = 1;
  813. Done = FALSE;
  814. Error = FALSE;
  815. //
  816. // Enter token processing loop
  817. //
  818. while (!Done) {
  819. Token = GetToken(File);
  820. switch (State) {
  821. //
  822. // STATE1: Start of file, this state remains till first
  823. // section is found
  824. // Valid Tokens: TOK_EOL, TOK_EOF, TOK_LBRACE
  825. case 1:
  826. switch (Token.Type) {
  827. case TOK_EOL:
  828. break;
  829. case TOK_EOF:
  830. Done = TRUE;
  831. break;
  832. case TOK_LBRACE:
  833. State = 2;
  834. break;
  835. default:
  836. Error = Done = TRUE;
  837. ErrorCode = EINVAL;
  838. break;
  839. }
  840. break;
  841. //
  842. // STATE 2: Section LBRACE has been received, expecting STRING
  843. //
  844. // Valid Tokens: TOK_STRING
  845. //
  846. case 2:
  847. switch (Token.Type) {
  848. case TOK_STRING:
  849. State = 3;
  850. pchSectionName = Token.pValue;
  851. break;
  852. default:
  853. Error = Done = TRUE;
  854. ErrorCode = EINVAL;
  855. break;
  856. }
  857. break;
  858. //
  859. // STATE 3: Section Name received, expecting RBRACE
  860. //
  861. // Valid Tokens: TOK_RBRACE
  862. //
  863. case 3:
  864. switch (Token.Type) {
  865. case TOK_RBRACE:
  866. State = 4;
  867. break;
  868. default:
  869. Error = Done = TRUE;
  870. ErrorCode = EINVAL;
  871. break;
  872. }
  873. break;
  874. //
  875. // STATE 4: Section Definition Complete, expecting EOL
  876. //
  877. // Valid Tokens: TOK_EOL, TOK_EOF
  878. //
  879. case 4:
  880. switch (Token.Type) {
  881. case TOK_EOL:
  882. LastSection = AddSection (InfHandle, pchSectionName);
  883. FREE (pchSectionName);
  884. pchSectionName = NULL;
  885. State = 5;
  886. break;
  887. case TOK_EOF:
  888. LastSection = AddSection (InfHandle, pchSectionName);
  889. FREE (pchSectionName);
  890. pchSectionName = NULL;
  891. Done = TRUE;
  892. break;
  893. default:
  894. Error = Done = TRUE;
  895. ErrorCode = EINVAL;
  896. break;
  897. }
  898. break;
  899. //
  900. // STATE 5: Expecting Section Lines
  901. //
  902. // Valid Tokens: TOK_EOL, TOK_EOF, TOK_STRING, TOK_LBRACE
  903. //
  904. case 5:
  905. switch (Token.Type) {
  906. case TOK_EOL:
  907. break;
  908. case TOK_EOF:
  909. Done = TRUE;
  910. break;
  911. case TOK_STRING:
  912. pchValue = Token.pValue;
  913. State = 6;
  914. break;
  915. case TOK_LBRACE:
  916. State = 2;
  917. break;
  918. default:
  919. Error = Done = TRUE;
  920. ErrorCode = EINVAL;
  921. break;
  922. }
  923. break;
  924. //
  925. // STATE 6: String returned, not sure whether it is key or value
  926. //
  927. // Valid Tokens: TOK_EOL, TOK_EOF, TOK_COMMA, TOK_EQUAL
  928. //
  929. case 6:
  930. switch (Token.Type) {
  931. case TOK_EOL:
  932. LastLine = AddLine (InfHandle, LastSection, NULL);
  933. AddValue (InfHandle, LastLine, pchValue);
  934. FREE (pchValue);
  935. pchValue = NULL;
  936. State = 5;
  937. break;
  938. case TOK_EOF:
  939. LastLine = AddLine (InfHandle, LastSection, NULL);
  940. AddValue (InfHandle, LastLine, pchValue);
  941. FREE (pchValue);
  942. pchValue = NULL;
  943. Done = TRUE;
  944. break;
  945. case TOK_COMMA:
  946. LastLine = AddLine (InfHandle, LastSection, NULL);
  947. AddValue (InfHandle, LastLine, pchValue);
  948. FREE (pchValue);
  949. pchValue = NULL;
  950. State = 7;
  951. break;
  952. case TOK_EQUAL:
  953. LastLine = AddLine (InfHandle, LastSection, pchValue);
  954. FREE (pchValue);
  955. pchValue = NULL;
  956. State = 8;
  957. break;
  958. default:
  959. Error = Done = TRUE;
  960. ErrorCode = EINVAL;
  961. break;
  962. }
  963. break;
  964. //
  965. // STATE 7: Comma received, Expecting another string
  966. //
  967. // Valid Tokens: TOK_STRING
  968. //
  969. case 7:
  970. switch (Token.Type) {
  971. case TOK_STRING:
  972. AddValue (InfHandle, LastLine, Token.pValue);
  973. State = 9;
  974. break;
  975. case TOK_COMMA:
  976. AddValue (InfHandle, LastLine, NULL);
  977. State = 7;
  978. break;
  979. default:
  980. Error = Done = TRUE;
  981. ErrorCode = EINVAL;
  982. break;
  983. }
  984. break;
  985. //
  986. // STATE 8: Equal received, Expecting another string
  987. //
  988. // Valid Tokens: TOK_STRING
  989. //
  990. case 8:
  991. switch (Token.Type) {
  992. case TOK_STRING:
  993. AddValue (InfHandle, LastLine, Token.pValue);
  994. State = 9;
  995. break;
  996. default:
  997. Error = Done = TRUE;
  998. ErrorCode = EINVAL;
  999. break;
  1000. }
  1001. break;
  1002. //
  1003. // STATE 9: String received after equal, value string
  1004. //
  1005. // Valid Tokens: TOK_EOL, TOK_EOF, TOK_COMMA
  1006. //
  1007. case 9:
  1008. switch (Token.Type) {
  1009. case TOK_EOL:
  1010. State = 5;
  1011. break;
  1012. case TOK_EOF:
  1013. Done = TRUE;
  1014. break;
  1015. case TOK_COMMA:
  1016. State = 7;
  1017. break;
  1018. default:
  1019. Error = Done = TRUE;
  1020. ErrorCode = EINVAL;
  1021. break;
  1022. }
  1023. break;
  1024. //
  1025. // STATE 10: Value string definitely received
  1026. //
  1027. // Valid Tokens: TOK_EOL, TOK_EOF, TOK_COMMA
  1028. //
  1029. case 10:
  1030. switch (Token.Type) {
  1031. case TOK_EOL:
  1032. State =5;
  1033. break;
  1034. case TOK_EOF:
  1035. Done = TRUE;
  1036. break;
  1037. case TOK_COMMA:
  1038. State = 7;
  1039. break;
  1040. default:
  1041. Error = Done = TRUE;
  1042. ErrorCode = EINVAL;
  1043. break;
  1044. }
  1045. break;
  1046. default:
  1047. Error = Done = TRUE;
  1048. ErrorCode = EINVAL;
  1049. break;
  1050. } // end switch(State)
  1051. if (Error) {
  1052. switch (ErrorCode) {
  1053. case ENOMEM:
  1054. DnFatalError(&DnsOutOfMemory);
  1055. default:
  1056. break;
  1057. }
  1058. }
  1059. else {
  1060. //
  1061. // Keep track of line numbers so that we can display Errors
  1062. //
  1063. if (Token.Type == TOK_EOL)
  1064. InfLine++;
  1065. }
  1066. } // End while
  1067. if (Error) {
  1068. *LineNumber = InfLine;
  1069. }
  1070. return (BOOLEAN) (!Error);
  1071. }
  1072. BOOLEAN
  1073. TokenMatch (
  1074. IN OUT char **p,
  1075. IN char *line
  1076. )
  1077. /*++
  1078. Routine Description:
  1079. This function tries to match to string pointed to be line against
  1080. a set of commonly used stirngs. If we hit, we'll assign p to
  1081. point to the matched string.
  1082. Arguments:
  1083. p - Supplies a char pointer that we'll assign if we find a match.
  1084. line - Supplies the address of the string we're trying to match.
  1085. Return Value:
  1086. TRUE - we found a match and have assigned p
  1087. FALSE - we found no match and made no assignment to p
  1088. --*/
  1089. {
  1090. int i;
  1091. if( (p == NULL) || (line == NULL) ) {
  1092. return( FALSE );
  1093. }
  1094. for( i = 0; i < sizeof(CommonStrings)/sizeof(char *); i++ ) {
  1095. if( !strcmp( line, CommonStrings[i] ) ) {
  1096. //
  1097. // Hit...
  1098. //
  1099. *p = (char *)CommonStrings[i];
  1100. return( TRUE );
  1101. }
  1102. }
  1103. return( FALSE );
  1104. }
  1105. TOKEN
  1106. GetToken(
  1107. IN FILE *File
  1108. )
  1109. /*++
  1110. Routine Description:
  1111. This function returns the Next token from the configuration stream.
  1112. Arguments:
  1113. Stream - Supplies the address of the configuration stream. Returns
  1114. the address of where to start looking for tokens within the
  1115. stream.
  1116. MaxStream - Supplies the address of the last character in the stream.
  1117. Return Value:
  1118. TOKEN - Returns the next token
  1119. --*/
  1120. {
  1121. int i;
  1122. unsigned Length;
  1123. TOKEN Token;
  1124. #define _MAXLINE 1024
  1125. static char line[_MAXLINE+1];
  1126. char *p;
  1127. //
  1128. // Skip whitespace (except for eol)
  1129. //
  1130. while(((i = fgetc(File)) != EOF) && (i != '\n') && (isspace(i) || (i == 26))) {
  1131. ;
  1132. }
  1133. //
  1134. // Check for comments and remove them
  1135. //
  1136. if((i != EOF) && ((i == '#') || (i == ';'))) {
  1137. while(((i = fgetc(File)) != EOF) && (i != '\n')) {
  1138. ;
  1139. }
  1140. }
  1141. //
  1142. // Check to see if EOF has been reached, set the token to the right
  1143. // value
  1144. //
  1145. if(i == EOF) {
  1146. Token.Type = TOK_EOF;
  1147. Token.pValue = NULL;
  1148. return(Token);
  1149. }
  1150. switch(i) {
  1151. case '[' :
  1152. Token.Type = TOK_LBRACE;
  1153. Token.pValue = NULL;
  1154. break;
  1155. case ']' :
  1156. Token.Type = TOK_RBRACE;
  1157. Token.pValue = NULL;
  1158. break;
  1159. case '=' :
  1160. Token.Type = TOK_EQUAL;
  1161. Token.pValue = NULL;
  1162. break;
  1163. case ',' :
  1164. Token.Type = TOK_COMMA;
  1165. Token.pValue = NULL;
  1166. break;
  1167. case '\n' :
  1168. Token.Type = TOK_EOL;
  1169. Token.pValue = NULL;
  1170. break;
  1171. case '\"':
  1172. //
  1173. // determine quoted string
  1174. //
  1175. Length = 0;
  1176. while(((i = fgetc(File)) != EOF) && !strchr(QStringTerminators,i)) {
  1177. if(Length < _MAXLINE) {
  1178. line[Length++] = (char)i;
  1179. }
  1180. }
  1181. if((i == EOF) || (i != '\"')) {
  1182. Token.Type = TOK_ERRPARSE;
  1183. Token.pValue = NULL;
  1184. } else {
  1185. line[Length] = 0;
  1186. p = MALLOC(Length+1,TRUE);
  1187. strcpy(p,line);
  1188. Token.Type = TOK_STRING;
  1189. Token.pValue = p;
  1190. }
  1191. break;
  1192. default:
  1193. //
  1194. // determine regular string
  1195. //
  1196. line[0] = (char)i;
  1197. Length = 1;
  1198. while(((i = fgetc(File)) != EOF) && !strchr(StringTerminators,i)) {
  1199. if(Length < _MAXLINE) {
  1200. line[Length++] = (char)i;
  1201. }
  1202. }
  1203. //
  1204. // Put back the char that terminated the string.
  1205. //
  1206. if(i != EOF) {
  1207. ungetc(i,File);
  1208. }
  1209. line[Length] = 0;
  1210. //
  1211. // See if we can use one of the common strings.
  1212. //
  1213. if( !TokenMatch ( &p, line ) ) {
  1214. //
  1215. // Nope.
  1216. //
  1217. p = MALLOC(Length+1,TRUE);
  1218. strcpy(p,line);
  1219. }
  1220. else {
  1221. char *p1;
  1222. p1 = MALLOC (strlen(p)+1, TRUE);
  1223. strcpy (p1, p);
  1224. p = p1;
  1225. }
  1226. Token.Type = TOK_STRING;
  1227. Token.pValue = p;
  1228. break;
  1229. }
  1230. return(Token);
  1231. }
  1232. BOOLEAN
  1233. DnSearchINFSection (
  1234. IN PVOID INFHandle,
  1235. IN PCHAR SectionName
  1236. )
  1237. {
  1238. return (BOOLEAN) (SearchSectionByName ((PSWAP_INF)INFHandle, SectionName) != NULL_HANDLE);
  1239. }
  1240. PCHAR
  1241. DnGetSectionLineIndex (
  1242. IN PVOID INFHandle,
  1243. IN PCHAR SectionName,
  1244. IN unsigned LineIndex,
  1245. IN unsigned ValueIndex
  1246. )
  1247. {
  1248. SECTION_HANDLE SectionHandle;
  1249. LINE_HANDLE LineHandle;
  1250. VALUE_HANDLE ValueHandle;
  1251. PSWAP_VALUE Value;
  1252. PCHAR result;
  1253. SectionHandle = SearchSectionByName ((PSWAP_INF)INFHandle, SectionName);
  1254. if (!SectionHandle) {
  1255. return NULL;
  1256. }
  1257. LineHandle = SearchLineInSectionByIndex ((PSWAP_INF)INFHandle, SectionHandle, LineIndex);
  1258. if (!LineHandle) {
  1259. return NULL;
  1260. }
  1261. ValueHandle = SearchValueInLineByIndex ((PSWAP_INF)INFHandle, LineHandle, ValueIndex);
  1262. if (!ValueHandle) {
  1263. return NULL;
  1264. }
  1265. Value = GetValuePtr ((PSWAP_INF)INFHandle, ValueHandle);
  1266. result = MALLOC (Value->ValueSize - sizeof(SWAP_VALUE), TRUE);
  1267. strcpy (result, Value->ValueName);
  1268. return result;
  1269. }
  1270. BOOLEAN
  1271. DnGetSectionKeyExists (
  1272. IN PVOID INFHandle,
  1273. IN PCHAR SectionName,
  1274. IN PCHAR Key
  1275. )
  1276. {
  1277. SECTION_HANDLE SectionHandle;
  1278. SectionHandle = SearchSectionByName ((PSWAP_INF)INFHandle, SectionName);
  1279. if (!SectionHandle) {
  1280. return FALSE;
  1281. }
  1282. return (BOOLEAN) (SearchLineInSectionByName ((PSWAP_INF)INFHandle, SectionHandle, Key) != NULL_HANDLE);
  1283. }
  1284. BOOLEAN
  1285. DnGetSectionEntryExists (
  1286. IN PVOID INFHandle,
  1287. IN PCHAR SectionName,
  1288. IN PCHAR Entry
  1289. )
  1290. {
  1291. SECTION_HANDLE SectionHandle;
  1292. LINE_HANDLE LineHandle;
  1293. PSWAP_SECTION SectionPtr=NULL;
  1294. PSWAP_LINE LinePtr=NULL;
  1295. PSWAP_VALUE ValuePtr=NULL;
  1296. PCHAR pEntryName;
  1297. SectionHandle = SearchSectionByName ((PSWAP_INF)INFHandle, SectionName);
  1298. if (!SectionHandle) {
  1299. return FALSE;
  1300. }
  1301. //_LOG(("Found [%s]\n", SectionName));
  1302. SectionPtr = GetSectionPtr((PSWAP_INF)INFHandle, SectionHandle);
  1303. LineHandle = SectionPtr->FirstLine;
  1304. while( LineHandle ){
  1305. LinePtr = GetLinePtr((PSWAP_INF)INFHandle, LineHandle);
  1306. pEntryName = NULL;
  1307. if( LinePtr->LineName[0] != 0){
  1308. pEntryName = LinePtr->LineName;
  1309. // _LOG(("Found Line %s\n", pEntryName));
  1310. }else{
  1311. ValuePtr = GetValuePtr((PSWAP_INF)INFHandle, LinePtr->FirstValue);
  1312. if (ValuePtr && (ValuePtr->ValueName[0] != 0)) {
  1313. pEntryName = ValuePtr->ValueName;
  1314. }else
  1315. pEntryName = NULL;
  1316. }
  1317. //_LOG(("Found Entry %s\n", pEntryName));
  1318. if( pEntryName && !stricmp( pEntryName, Entry )){
  1319. return TRUE;
  1320. }
  1321. LineHandle = GetNextLine((PSWAP_INF)INFHandle, LineHandle);
  1322. }// while
  1323. return FALSE;
  1324. }
  1325. PCHAR
  1326. DnGetSectionKeyIndex (
  1327. IN PVOID INFHandle,
  1328. IN PCHAR SectionName,
  1329. IN PCHAR Key,
  1330. IN unsigned ValueIndex
  1331. )
  1332. {
  1333. SECTION_HANDLE SectionHandle;
  1334. LINE_HANDLE LineHandle;
  1335. VALUE_HANDLE ValueHandle;
  1336. PSWAP_VALUE Value;
  1337. PCHAR result;
  1338. SectionHandle = SearchSectionByName ((PSWAP_INF)INFHandle, SectionName);
  1339. if (!SectionHandle) {
  1340. return NULL;
  1341. }
  1342. LineHandle = SearchLineInSectionByName ((PSWAP_INF)INFHandle, SectionHandle, Key);
  1343. if (!LineHandle) {
  1344. return NULL;
  1345. }
  1346. ValueHandle = SearchValueInLineByIndex ((PSWAP_INF)INFHandle, LineHandle, ValueIndex);
  1347. if (!ValueHandle) {
  1348. return NULL;
  1349. }
  1350. Value = GetValuePtr ((PSWAP_INF)INFHandle, ValueHandle);
  1351. result = MALLOC (Value->ValueSize - sizeof(SWAP_VALUE), TRUE);
  1352. strcpy (result, Value->ValueName);
  1353. return result;
  1354. }
  1355. PCHAR
  1356. DnGetKeyName (
  1357. IN PVOID INFHandle,
  1358. IN PCHAR SectionName,
  1359. IN unsigned LineIndex
  1360. )
  1361. {
  1362. SECTION_HANDLE SectionHandle;
  1363. LINE_HANDLE LineHandle;
  1364. PSWAP_LINE Line;
  1365. PCHAR result;
  1366. SectionHandle = SearchSectionByName ((PSWAP_INF)INFHandle, SectionName);
  1367. if (!SectionHandle) {
  1368. return NULL;
  1369. }
  1370. LineHandle = SearchLineInSectionByIndex ((PSWAP_INF)INFHandle, SectionHandle, LineIndex);
  1371. if (!LineHandle) {
  1372. return NULL;
  1373. }
  1374. Line = GetLinePtr ((PSWAP_INF)INFHandle, LineHandle);
  1375. result = MALLOC (Line->LineSize - sizeof(SWAP_LINE), TRUE);
  1376. strcpy (result, Line->LineName);
  1377. return result;
  1378. }
  1379. PVOID
  1380. DnNewSetupTextFile (
  1381. VOID
  1382. )
  1383. {
  1384. char SwapFilePath[MAX_PATH];
  1385. PSWAP_INF InfHandle = NULL;
  1386. unsigned long SwapSign;
  1387. //
  1388. // Prepare the swap file path
  1389. //
  1390. sprintf (SwapFilePath, "%c:\\INF%03u.SWP", DngSwapDriveLetter, g_Sequencer++);
  1391. //
  1392. // Allocate and populate the SWAP_INF structure
  1393. //
  1394. InfHandle = MALLOC(sizeof(SWAP_INF) + strlen (SwapFilePath) + 1, TRUE);
  1395. InfHandle->CurrentSection = NULL;
  1396. InfHandle->FirstSection = NULL;
  1397. InfHandle->LastSection = NULL;
  1398. InfHandle->SwapFileHandle = -1;
  1399. InfHandle->BufferSize = 0;
  1400. InfHandle->BufferDirty = FALSE;
  1401. InfHandle->Buffer = NULL;
  1402. InfHandle->BufferStart = 0;
  1403. InfHandle->BufferEnd = 0;
  1404. InfHandle->LastSectionHandle = NULL_HANDLE;
  1405. InfHandle->LastLineIndex = 0xffff;
  1406. InfHandle->LastLineHandle = NULL_HANDLE;
  1407. InfHandle->LastValueIndex = 0xffff;
  1408. InfHandle->LastValueHandle = NULL_HANDLE;
  1409. strcpy (InfHandle->SwapFile, SwapFilePath);
  1410. //
  1411. // Prepare the swap file
  1412. //
  1413. InfHandle->SwapFileHandle = open (InfHandle->SwapFile, O_BINARY|O_CREAT|O_TRUNC|O_RDWR, S_IREAD|S_IWRITE);
  1414. if (InfHandle->SwapFileHandle == -1) {
  1415. FREE (InfHandle);
  1416. return NULL;
  1417. }
  1418. else {
  1419. //
  1420. // write down signature
  1421. //
  1422. SwapSign = SWAP_SIGNATURE;
  1423. write (InfHandle->SwapFileHandle, &SwapSign, SWAP_SIGN_SIZE);
  1424. //
  1425. // Prepare the buffer
  1426. //
  1427. InfHandle->BufferSize = MAX_BUFFER_SIZE;
  1428. InfHandle->Buffer = MALLOC (MAX_BUFFER_SIZE, TRUE);
  1429. InfHandle->BufferStart = SWAP_SIGN_SIZE;
  1430. InfHandle->BufferEnd = SWAP_SIGN_SIZE;
  1431. return InfHandle;
  1432. }
  1433. }
  1434. BOOLEAN
  1435. DnWriteSetupTextFile (
  1436. IN PVOID INFHandle,
  1437. IN PCHAR FileName
  1438. )
  1439. {
  1440. struct find_t FindData;
  1441. FILE *Handle;
  1442. PSWAP_INF pInf;
  1443. SECTION_HANDLE Section;
  1444. PSWAP_SECTION SectionPtr;
  1445. LINE_HANDLE Line;
  1446. PSWAP_LINE LinePtr;
  1447. VALUE_HANDLE Value;
  1448. PSWAP_VALUE ValuePtr;
  1449. //
  1450. // See if the file exists and see if it is in read-only mode
  1451. //
  1452. if(!_dos_findfirst(FileName,_A_HIDDEN|_A_SUBDIR|_A_SYSTEM|_A_RDONLY,&FindData)) {
  1453. //
  1454. // The File Exists -- Perform some simple checks
  1455. //
  1456. if (FindData.attrib & _A_RDONLY) {
  1457. //
  1458. // Make it writeable
  1459. //
  1460. _dos_setfileattr(FileName,_A_NORMAL);
  1461. }
  1462. if (FindData.attrib & _A_SUBDIR) {
  1463. //
  1464. // This isn't a valid file that we can work with..
  1465. //
  1466. return FALSE;
  1467. }
  1468. }
  1469. //
  1470. // Obtain a handle to the file in write-only mode
  1471. //
  1472. Handle = fopen(FileName, "w+");
  1473. if (Handle == NULL) {
  1474. //
  1475. // We could not open the file
  1476. //
  1477. return FALSE;
  1478. }
  1479. pInf = (PSWAP_INF) INFHandle;
  1480. if (pInf == NULL) {
  1481. //
  1482. // There isn't anything in the file.
  1483. // That isn't an error since we can empty
  1484. // the file if we so desire, but this is a
  1485. // strange way todo that. However...
  1486. //
  1487. fclose(Handle);
  1488. return TRUE;
  1489. }
  1490. //
  1491. // NOTE - This can't handle > 64k buffers. Which may or may not be
  1492. // important
  1493. //
  1494. Section = pInf->FirstSection;
  1495. while (Section) {
  1496. SectionPtr = GetSectionPtr (pInf, Section);
  1497. fprintf (Handle, "[%s]\n", SectionPtr->SectionName);
  1498. Line = SectionPtr->FirstLine;
  1499. while (Line) {
  1500. LinePtr = GetLinePtr (pInf, Line);
  1501. if ((LinePtr->LineName) && (LinePtr->LineName[0])) {
  1502. if (strchr (LinePtr->LineName, ' ') == NULL) {
  1503. fprintf (Handle, "%s = ", LinePtr->LineName);
  1504. } else {
  1505. fprintf (Handle, "\"%s\" = ", LinePtr->LineName);
  1506. }
  1507. }
  1508. Value = LinePtr->FirstValue;
  1509. while (Value) {
  1510. ValuePtr = GetValuePtr (pInf, Value);
  1511. fprintf (Handle,"\"%s\"", ValuePtr->ValueName);
  1512. Value = GetNextValue (pInf, Value);
  1513. if (Value) {
  1514. fprintf (Handle, ",");
  1515. }
  1516. }
  1517. Line = GetNextLine (pInf, Line);
  1518. fprintf (Handle,"\n");
  1519. }
  1520. Section = GetNextSection (pInf, Section);
  1521. }
  1522. //
  1523. // Flush and Close the file
  1524. //
  1525. fflush(Handle);
  1526. fclose(Handle);
  1527. return TRUE;
  1528. }
  1529. VOID
  1530. DnAddLineToSection (
  1531. IN PVOID INFHandle,
  1532. IN PCHAR SectionName,
  1533. IN PCHAR KeyName,
  1534. IN PCHAR Values[],
  1535. IN ULONG ValueCount
  1536. )
  1537. {
  1538. SECTION_HANDLE SectionHandle;
  1539. LINE_HANDLE LineHandle;
  1540. VALUE_HANDLE ValueHandle;
  1541. ULONG v;
  1542. SectionHandle = AddSection ((PSWAP_INF)INFHandle, SectionName);
  1543. LineHandle = AddLine ((PSWAP_INF)INFHandle, SectionHandle, KeyName);
  1544. for (v = 0; v<ValueCount; v++) {
  1545. ValueHandle = AddValue ((PSWAP_INF)INFHandle, LineHandle, Values[v]);
  1546. }
  1547. }
  1548. PCHAR
  1549. DnGetSectionName (
  1550. IN PVOID INFHandle
  1551. )
  1552. {
  1553. PSWAP_INF pInf;
  1554. PSWAP_SECTION Section;
  1555. PCHAR result;
  1556. pInf = (PSWAP_INF)INFHandle;
  1557. if (!pInf->CurrentSection) {
  1558. pInf->CurrentSection = pInf->FirstSection;
  1559. }
  1560. else {
  1561. pInf->CurrentSection = GetNextSection (pInf, pInf->CurrentSection);
  1562. }
  1563. if (!pInf->CurrentSection) {
  1564. return NULL;
  1565. }
  1566. Section = GetSectionPtr (pInf, pInf->CurrentSection);
  1567. result = MALLOC (Section->SectionSize - sizeof(SWAP_SECTION), TRUE);
  1568. strcpy (result, Section->SectionName);
  1569. return result;
  1570. }
  1571. VOID
  1572. DnCopySetupTextSection (
  1573. IN PVOID FromInf,
  1574. IN PVOID ToInf,
  1575. IN PCHAR SectionName
  1576. )
  1577. {
  1578. PSWAP_INF SourceInf;
  1579. PSWAP_INF DestInf;
  1580. SECTION_HANDLE SourceSection;
  1581. SECTION_HANDLE DestSection;
  1582. PSWAP_SECTION SectionPtr;
  1583. LINE_HANDLE SourceLine;
  1584. LINE_HANDLE DestLine;
  1585. PSWAP_LINE LinePtr;
  1586. VALUE_HANDLE SourceValue;
  1587. VALUE_HANDLE DestValue;
  1588. PSWAP_VALUE ValuePtr;
  1589. SourceInf = (PSWAP_INF)FromInf;
  1590. DestInf = (PSWAP_INF)ToInf;
  1591. SourceSection = SearchSectionByName (FromInf, SectionName);
  1592. if (SourceSection) {
  1593. SectionPtr = GetSectionPtr (SourceInf, SourceSection);
  1594. DestSection = AddSection (DestInf, SectionPtr->SectionName);
  1595. if (DestSection) {
  1596. SourceLine = SectionPtr->FirstLine;
  1597. while (SourceLine) {
  1598. LinePtr = GetLinePtr (SourceInf, SourceLine);
  1599. //
  1600. // If the line already exists in the destination file, we'll
  1601. // be keeping the existing line.
  1602. //
  1603. if( SearchLineInSectionByName(DestInf, DestSection, LinePtr->LineName) == NULL_HANDLE ) {
  1604. //
  1605. // The line is not already there, so migrate it
  1606. //
  1607. DestLine = AddLine (DestInf, DestSection, LinePtr->LineName);
  1608. SourceValue = LinePtr->FirstValue;
  1609. while (SourceValue) {
  1610. ValuePtr = GetValuePtr (SourceInf, SourceValue);
  1611. DestValue = AddValue (DestInf, DestLine, ValuePtr->ValueName);
  1612. SourceValue = GetNextValue (SourceInf, SourceValue);
  1613. }
  1614. }
  1615. SourceLine = GetNextLine (SourceInf, SourceLine);
  1616. }
  1617. }
  1618. }
  1619. }