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.

644 lines
12 KiB

  1. /*++
  2. Copyright (c) 1993 Microsoft Corporation
  3. Module Name:
  4. infline.c
  5. Abstract:
  6. Externally exposed INF routines for INF line retreival and information.
  7. Author:
  8. Ted Miller (tedm) 20-Jan-1995
  9. Revision History:
  10. --*/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. #ifdef UNICODE
  14. //
  15. // ANSI version
  16. //
  17. BOOL
  18. SetupFindFirstLineA(
  19. IN HINF InfHandle,
  20. IN PCSTR Section,
  21. IN PCSTR Key, OPTIONAL
  22. OUT PINFCONTEXT Context
  23. )
  24. {
  25. PCTSTR section,key;
  26. BOOL b;
  27. DWORD d;
  28. if((d = pSetupCaptureAndConvertAnsiArg(Section,&section)) != NO_ERROR) {
  29. //
  30. // Invalid arg.
  31. //
  32. SetLastError(d);
  33. return(FALSE);
  34. }
  35. if(Key) {
  36. if((d = pSetupCaptureAndConvertAnsiArg(Key,&key)) != NO_ERROR) {
  37. //
  38. // Invalid arg.
  39. //
  40. MyFree(section);
  41. SetLastError(d);
  42. return(FALSE);
  43. }
  44. } else {
  45. key = NULL;
  46. }
  47. b = SetupFindFirstLine(InfHandle,section,key,Context);
  48. //
  49. // We're safe in calling this here regardless of success or failure, since
  50. // we are ensured that SetupFindFirstLine will always call SetLastError().
  51. //
  52. d = GetLastError();
  53. if(key) {
  54. MyFree(key);
  55. }
  56. MyFree(section);
  57. SetLastError(d);
  58. return(b);
  59. }
  60. #else
  61. //
  62. // Unicode stub
  63. //
  64. BOOL
  65. SetupFindFirstLineW(
  66. IN HINF InfHandle,
  67. IN PCWSTR Section,
  68. IN PCWSTR Key, OPTIONAL
  69. OUT PINFCONTEXT Context
  70. )
  71. {
  72. UNREFERENCED_PARAMETER(InfHandle);
  73. UNREFERENCED_PARAMETER(Section);
  74. UNREFERENCED_PARAMETER(Key);
  75. UNREFERENCED_PARAMETER(Context);
  76. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  77. return(FALSE);
  78. }
  79. #endif
  80. BOOL
  81. SetupFindFirstLine(
  82. IN HINF InfHandle,
  83. IN PCTSTR Section,
  84. IN PCTSTR Key, OPTIONAL
  85. OUT PINFCONTEXT Context
  86. )
  87. /*++
  88. Routine Description:
  89. Arguments:
  90. Return Value:
  91. --*/
  92. {
  93. PLOADED_INF CurInf;
  94. PINF_SECTION InfSection;
  95. PINF_LINE InfLine;
  96. UINT LineNumber;
  97. UINT SectionNumber;
  98. DWORD d;
  99. d = NO_ERROR;
  100. try {
  101. if(!LockInf((PLOADED_INF)InfHandle)) {
  102. d = ERROR_INVALID_HANDLE;
  103. }
  104. } except(EXCEPTION_EXECUTE_HANDLER) {
  105. //
  106. // Assume InfHandle was bad pointer
  107. //
  108. d = ERROR_INVALID_HANDLE;
  109. }
  110. if(d != NO_ERROR) {
  111. SetLastError(d);
  112. return(FALSE);
  113. }
  114. //
  115. // Traverse the linked list of loaded INFs, looking for the specified
  116. // section.
  117. //
  118. try {
  119. for(CurInf = (PLOADED_INF)InfHandle; CurInf; CurInf = CurInf->Next) {
  120. //
  121. // Locate the section.
  122. //
  123. if(!(InfSection = InfLocateSection(CurInf, Section, &SectionNumber))) {
  124. continue;
  125. }
  126. //
  127. // Attempt to locate the line within this section.
  128. //
  129. LineNumber = 0;
  130. if(InfLocateLine(CurInf, InfSection, Key, &LineNumber, &InfLine)) {
  131. break;
  132. }
  133. }
  134. } except(EXCEPTION_EXECUTE_HANDLER) {
  135. d = ERROR_INVALID_PARAMETER;
  136. }
  137. UnlockInf((PLOADED_INF)InfHandle);
  138. if(d != NO_ERROR) {
  139. SetLastError(d);
  140. return(FALSE);
  141. }
  142. if(CurInf) {
  143. //
  144. // Then we found the specified line.
  145. //
  146. MYASSERT(Key || !LineNumber);
  147. try {
  148. Context->Inf = (PVOID)InfHandle;
  149. Context->CurrentInf = (PVOID)CurInf;
  150. Context->Section = SectionNumber;
  151. Context->Line = LineNumber;
  152. } except(EXCEPTION_EXECUTE_HANDLER) {
  153. d = ERROR_INVALID_PARAMETER;
  154. }
  155. } else {
  156. d = ERROR_LINE_NOT_FOUND;
  157. }
  158. SetLastError(d);
  159. return(d == NO_ERROR);
  160. }
  161. BOOL
  162. SetupFindNextLine(
  163. IN PINFCONTEXT ContextIn,
  164. OUT PINFCONTEXT ContextOut
  165. )
  166. /*++
  167. Routine Description:
  168. Arguments:
  169. Return Value:
  170. --*/
  171. {
  172. return(SetupFindNextMatchLine(ContextIn,NULL,ContextOut));
  173. }
  174. #ifdef UNICODE
  175. //
  176. // ANSI version
  177. //
  178. BOOL
  179. SetupFindNextMatchLineA(
  180. IN PINFCONTEXT ContextIn,
  181. IN PCSTR Key, OPTIONAL
  182. OUT PINFCONTEXT ContextOut
  183. )
  184. {
  185. PWSTR key;
  186. BOOL b;
  187. DWORD d;
  188. if(!Key) {
  189. key = NULL;
  190. d = NO_ERROR;
  191. } else {
  192. d = pSetupCaptureAndConvertAnsiArg(Key,&key);
  193. }
  194. if (d == NO_ERROR) {
  195. b = SetupFindNextMatchLineW(ContextIn,key,ContextOut);
  196. d = GetLastError();
  197. if (key) {
  198. MyFree(key);
  199. }
  200. } else {
  201. b = FALSE;
  202. }
  203. SetLastError(d);
  204. return(b);
  205. }
  206. #else
  207. //
  208. // Unicode stub
  209. //
  210. BOOL
  211. SetupFindNextMatchLineW(
  212. IN PINFCONTEXT ContextIn,
  213. IN PCWSTR Key, OPTIONAL
  214. OUT PINFCONTEXT ContextOut
  215. )
  216. {
  217. UNREFERENCED_PARAMETER(ContextIn);
  218. UNREFERENCED_PARAMETER(Key);
  219. UNREFERENCED_PARAMETER(ContextOut);
  220. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  221. return(FALSE);
  222. }
  223. #endif
  224. BOOL
  225. SetupFindNextMatchLine(
  226. IN PINFCONTEXT ContextIn,
  227. IN PCTSTR Key, OPTIONAL
  228. OUT PINFCONTEXT ContextOut
  229. )
  230. /*++
  231. Routine Description:
  232. Arguments:
  233. Return Value:
  234. --*/
  235. {
  236. PLOADED_INF CurInf;
  237. UINT LineNumber;
  238. UINT SectionNumber;
  239. PINF_LINE Line;
  240. PINF_SECTION Section;
  241. PCTSTR SectionName;
  242. DWORD d;
  243. d = NO_ERROR;
  244. try {
  245. if(!LockInf((PLOADED_INF)ContextIn->Inf)) {
  246. d = ERROR_INVALID_HANDLE;
  247. }
  248. } except(EXCEPTION_EXECUTE_HANDLER) {
  249. //
  250. // ContextIn is a bad pointer
  251. //
  252. d = ERROR_INVALID_PARAMETER;
  253. }
  254. if(d != NO_ERROR) {
  255. SetLastError(d);
  256. return(FALSE);
  257. }
  258. //
  259. // Fetch values from context
  260. //
  261. try {
  262. CurInf = ContextIn->CurrentInf;
  263. SectionNumber = ContextIn->Section;
  264. Section = &CurInf->SectionBlock[SectionNumber];
  265. SectionName = pStringTableStringFromId(CurInf->StringTable, Section->SectionName);
  266. MYASSERT(SectionName);
  267. //
  268. // Either want next line, or to start searching for key on next line
  269. //
  270. LineNumber = ContextIn->Line+1;
  271. do {
  272. if(Section) {
  273. if(InfLocateLine(CurInf, Section, Key, &LineNumber, &Line)) {
  274. break;
  275. }
  276. }
  277. if(CurInf = CurInf->Next) {
  278. Section = InfLocateSection(CurInf, SectionName, &SectionNumber);
  279. LineNumber = 0;
  280. }
  281. } while(CurInf);
  282. } except(EXCEPTION_EXECUTE_HANDLER) {
  283. d = ERROR_INVALID_PARAMETER;
  284. }
  285. UnlockInf((PLOADED_INF)ContextIn->Inf);
  286. if(d != NO_ERROR) {
  287. SetLastError(d);
  288. return(FALSE);
  289. }
  290. if(CurInf) {
  291. //
  292. // Then we found the next line.
  293. //
  294. try {
  295. ContextOut->Inf = ContextIn->Inf;
  296. ContextOut->CurrentInf = CurInf;
  297. ContextOut->Section = SectionNumber;
  298. ContextOut->Line = LineNumber;
  299. } except(EXCEPTION_EXECUTE_HANDLER) {
  300. d = ERROR_INVALID_PARAMETER;
  301. }
  302. } else {
  303. d = ERROR_LINE_NOT_FOUND;
  304. }
  305. SetLastError(d);
  306. return(d == NO_ERROR);
  307. }
  308. #ifdef UNICODE
  309. //
  310. // ANSI version
  311. //
  312. BOOL
  313. SetupGetLineByIndexA(
  314. IN HINF InfHandle,
  315. IN PCSTR Section,
  316. IN DWORD Index,
  317. OUT PINFCONTEXT Context
  318. )
  319. {
  320. PCWSTR section;
  321. DWORD d;
  322. BOOL b;
  323. if((d = pSetupCaptureAndConvertAnsiArg(Section,&section)) == NO_ERROR) {
  324. b = SetupGetLineByIndexW(InfHandle,section,Index,Context);
  325. d = GetLastError();
  326. MyFree(section);
  327. } else {
  328. b = FALSE;
  329. }
  330. SetLastError(d);
  331. return(b);
  332. }
  333. #else
  334. //
  335. // Unicode stub
  336. //
  337. BOOL
  338. SetupGetLineByIndexW(
  339. IN HINF InfHandle,
  340. IN PCWSTR Section,
  341. IN DWORD Index,
  342. OUT PINFCONTEXT Context
  343. )
  344. {
  345. UNREFERENCED_PARAMETER(InfHandle);
  346. UNREFERENCED_PARAMETER(Section);
  347. UNREFERENCED_PARAMETER(Index);
  348. UNREFERENCED_PARAMETER(Context);
  349. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  350. return(FALSE);
  351. }
  352. #endif
  353. BOOL
  354. SetupGetLineByIndex(
  355. IN HINF InfHandle,
  356. IN PCTSTR Section,
  357. IN DWORD Index,
  358. OUT PINFCONTEXT Context
  359. )
  360. /*++
  361. Routine Description:
  362. Arguments:
  363. Return Value:
  364. --*/
  365. {
  366. PLOADED_INF CurInf;
  367. PINF_SECTION InfSection;
  368. PINF_LINE InfLine;
  369. UINT LineNumber, CurLineNumberUB;
  370. UINT SectionNumber;
  371. DWORD d;
  372. d = NO_ERROR;
  373. try {
  374. if(!LockInf((PLOADED_INF)InfHandle)) {
  375. d = ERROR_INVALID_HANDLE;
  376. }
  377. } except(EXCEPTION_EXECUTE_HANDLER) {
  378. d = ERROR_INVALID_HANDLE;
  379. }
  380. if(d != NO_ERROR) {
  381. SetLastError(d);
  382. return(FALSE);
  383. }
  384. try {
  385. //
  386. // Traverse the list of loaded INFs. For each INF that contains
  387. // the specified section, we check to see if the line number we're
  388. // looking for lies within its (adjusted) range of line numbers.
  389. //
  390. CurLineNumberUB = 0;
  391. for(CurInf = (PLOADED_INF)InfHandle; CurInf; CurInf = CurInf->Next) {
  392. //
  393. // Locate the section.
  394. //
  395. if(!(InfSection = InfLocateSection(CurInf, Section, &SectionNumber))) {
  396. continue;
  397. }
  398. //
  399. // See if the line number lies in this INF section's range.
  400. //
  401. MYASSERT(Index >= CurLineNumberUB);
  402. LineNumber = Index - CurLineNumberUB;
  403. if(InfLocateLine(CurInf, InfSection, NULL, &LineNumber, &InfLine)) {
  404. break;
  405. } else {
  406. //
  407. // Subtract the number of lines this INF contributes to the section's
  408. // total line count, and continue with the next one.
  409. //
  410. CurLineNumberUB += InfSection->LineCount;
  411. }
  412. }
  413. } except(EXCEPTION_EXECUTE_HANDLER) {
  414. d = ERROR_INVALID_PARAMETER;
  415. }
  416. UnlockInf((PLOADED_INF)InfHandle);
  417. if(d != NO_ERROR) {
  418. SetLastError(d);
  419. return(FALSE);
  420. }
  421. if(CurInf) {
  422. //
  423. // Then we found the specified line.
  424. //
  425. try {
  426. Context->Inf = (PVOID)InfHandle;
  427. Context->CurrentInf = (PVOID)CurInf;
  428. Context->Section = SectionNumber;
  429. Context->Line = LineNumber;
  430. } except(EXCEPTION_EXECUTE_HANDLER) {
  431. d = ERROR_INVALID_PARAMETER;
  432. }
  433. } else {
  434. d = ERROR_LINE_NOT_FOUND;
  435. }
  436. SetLastError(d);
  437. return(d == NO_ERROR);
  438. }
  439. #ifdef UNICODE
  440. //
  441. // ANSI version
  442. //
  443. LONG
  444. SetupGetLineCountA(
  445. IN HINF InfHandle,
  446. IN PCSTR Section
  447. )
  448. {
  449. PCWSTR section;
  450. LONG l;
  451. DWORD d;
  452. if((d = pSetupCaptureAndConvertAnsiArg(Section,&section)) == NO_ERROR) {
  453. l = SetupGetLineCountW(InfHandle,section);
  454. d = GetLastError();
  455. MyFree(section);
  456. } else {
  457. l = -1;
  458. }
  459. SetLastError(d);
  460. return(l);
  461. }
  462. #else
  463. //
  464. // Unicode stub
  465. //
  466. LONG
  467. SetupGetLineCountW(
  468. IN HINF InfHandle,
  469. IN PCWSTR Section
  470. )
  471. {
  472. UNREFERENCED_PARAMETER(InfHandle);
  473. UNREFERENCED_PARAMETER(Section);
  474. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  475. return(-1);
  476. }
  477. #endif
  478. LONG
  479. SetupGetLineCount(
  480. IN HINF InfHandle,
  481. IN PCTSTR Section
  482. )
  483. /*++
  484. Routine Description:
  485. Arguments:
  486. Return Value:
  487. --*/
  488. {
  489. PLOADED_INF CurInf;
  490. PINF_SECTION InfSection;
  491. LONG LineCount;
  492. DWORD d;
  493. d = NO_ERROR;
  494. try {
  495. if(!LockInf((PLOADED_INF)InfHandle)) {
  496. d = ERROR_INVALID_HANDLE;
  497. }
  498. } except(EXCEPTION_EXECUTE_HANDLER) {
  499. d = ERROR_INVALID_HANDLE;
  500. }
  501. if(d != NO_ERROR) {
  502. SetLastError(d);
  503. return(-1);
  504. }
  505. try {
  506. //
  507. // Traverse the linked list of loaded INFs, and sum up the section line
  508. // counts for each INF containing the specified section.
  509. //
  510. LineCount = -1;
  511. for(CurInf = (PLOADED_INF)InfHandle; CurInf; CurInf = CurInf->Next) {
  512. if(InfSection = InfLocateSection(CurInf, Section, NULL)) {
  513. if(LineCount == -1) {
  514. LineCount = InfSection->LineCount;
  515. } else {
  516. LineCount += InfSection->LineCount;
  517. }
  518. }
  519. }
  520. } except(EXCEPTION_EXECUTE_HANDLER) {
  521. d = ERROR_INVALID_PARAMETER;
  522. }
  523. UnlockInf((PLOADED_INF)InfHandle);
  524. if(d != NO_ERROR) {
  525. SetLastError(d);
  526. return(-1);
  527. }
  528. if(LineCount == -1) {
  529. SetLastError(ERROR_SECTION_NOT_FOUND);
  530. } else {
  531. SetLastError(NO_ERROR);
  532. }
  533. return LineCount;
  534. }