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.

932 lines
24 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. fileq3.c
  5. Abstract:
  6. Setup file queue routines for enqueing delete and rename
  7. operations.
  8. Author:
  9. Ted Miller (tedm) 15-Feb-1995
  10. Revision History:
  11. --*/
  12. #include "precomp.h"
  13. #pragma hdrstop
  14. BOOL
  15. _SetupQueueDelete(
  16. IN HSPFILEQ QueueHandle,
  17. IN PCTSTR PathPart1,
  18. IN PCTSTR PathPart2, OPTIONAL
  19. IN UINT Flags
  20. )
  21. /*++
  22. Routine Description:
  23. Place a delete operation on a setup file queue.
  24. Note that delete operations are assumed to be on fixed media.
  25. No prompting will be performed for delete operations when the
  26. queue is committed.
  27. Arguments:
  28. QueueHandle - supplies a handle to a setup file queue, as returned
  29. by SetupOpenFileQueue.
  30. PathPart1 - Supplies the first part of the path of
  31. the file to be deleted. If PathPart2 is not specified, then
  32. this is the full path of the file to be deleted.
  33. PathPart2 - if specified, supplies the second part of the path
  34. of the file to be deleted. This is concatenated to PathPart1
  35. to form the full pathname.
  36. Flags - specified flags controlling delete operation.
  37. DELFLG_IN_USE - if the file is in use, queue it for delayed
  38. delete, on next reboot. Otherwise in-use files are not deleted.
  39. DELFLG_IN_USE1 - same behavior as DELFLG_IN_USE--used when the
  40. same file list section is used for both a CopyFiles and DelFiles.
  41. (Since DELFLG_IN_USE (0x1) is also COPYFLG_WARN_IF_SKIP!)
  42. Return Value:
  43. Boolean value indicating outcome. If FALSE, GetLastError() returns
  44. extended error information.
  45. --*/
  46. {
  47. PSP_FILE_QUEUE Queue;
  48. PSP_FILE_QUEUE_NODE QueueNode, TempNode, PrevQueueNode;
  49. Queue = (PSP_FILE_QUEUE)QueueHandle;
  50. //
  51. // Allocate a queue structure.
  52. //
  53. QueueNode = MyMalloc(sizeof(SP_FILE_QUEUE_NODE));
  54. if(!QueueNode) {
  55. goto clean0;
  56. }
  57. ZeroMemory(QueueNode, sizeof(SP_FILE_QUEUE_NODE));
  58. //
  59. // Operation is delete.
  60. //
  61. QueueNode->Operation = FILEOP_DELETE;
  62. //
  63. // Initialize unused fields.
  64. //
  65. QueueNode->SourceRootPath = -1;
  66. QueueNode->SourcePath = -1;
  67. QueueNode->SourceFilename = -1;
  68. //
  69. // Set internal flag to indicate whether we should queue a delayed delete
  70. // for this file if it's in-use.
  71. //
  72. QueueNode->InternalFlags = (Flags & (DELFLG_IN_USE|DELFLG_IN_USE1)) ?
  73. IQF_DELAYED_DELETE_OK : 0;
  74. //
  75. // NOTE: When adding the following strings to the string table, we cast away
  76. // their CONST-ness to avoid a compiler warning. Since we are adding them
  77. // case-sensitively, we are guaranteed they will not be modified.
  78. //
  79. //
  80. // Set up the target directory.
  81. //
  82. QueueNode->TargetDirectory = pSetupStringTableAddString(Queue->StringTable,
  83. (PTSTR)PathPart1,
  84. STRTAB_CASE_SENSITIVE
  85. );
  86. if(QueueNode->TargetDirectory == -1) {
  87. goto clean1;
  88. }
  89. //
  90. // Set up the target filename.
  91. //
  92. if(PathPart2) {
  93. QueueNode->TargetFilename = pSetupStringTableAddString(Queue->StringTable,
  94. (PTSTR)PathPart2,
  95. STRTAB_CASE_SENSITIVE
  96. );
  97. if(QueueNode->TargetFilename == -1) {
  98. goto clean1;
  99. }
  100. } else {
  101. QueueNode->TargetFilename = -1;
  102. }
  103. //
  104. // Link the node onto the end of the delete queue.
  105. //
  106. QueueNode->Next = NULL;
  107. if(Queue->DeleteQueue) {
  108. //
  109. // Check to see if this same rename operation has already been enqueued,
  110. // and if so, get rid of the new one, to avoid duplicates. NOTE: We
  111. // don't check the "InternalFlags" field, since if the node already
  112. // exists in the queue (based on all the other relevant fields comparing
  113. // successfully), then any internal flags that were set on the
  114. // previously-existing node should be preserved (i.e., our new node
  115. // always is created with InternalFlags set to zero).
  116. //
  117. for(TempNode=Queue->DeleteQueue, PrevQueueNode = NULL;
  118. TempNode;
  119. PrevQueueNode = TempNode, TempNode=TempNode->Next) {
  120. if((TempNode->TargetDirectory == QueueNode->TargetDirectory) &&
  121. (TempNode->TargetFilename == QueueNode->TargetFilename)) {
  122. //
  123. // We've found a duplicate. However, we need to make sure that
  124. // if our new node specifies "delayed delete OK", then the
  125. // existing node has that internal flag set as well.
  126. //
  127. MYASSERT(!(QueueNode->InternalFlags & ~IQF_DELAYED_DELETE_OK));
  128. if(QueueNode->InternalFlags & IQF_DELAYED_DELETE_OK) {
  129. TempNode->InternalFlags |= IQF_DELAYED_DELETE_OK;
  130. }
  131. //
  132. // Kill the newly-created queue node and return success.
  133. //
  134. MyFree(QueueNode);
  135. return TRUE;
  136. }
  137. }
  138. MYASSERT(PrevQueueNode);
  139. PrevQueueNode->Next = QueueNode;
  140. } else {
  141. Queue->DeleteQueue = QueueNode;
  142. }
  143. Queue->DeleteNodeCount++;
  144. return(TRUE);
  145. clean1:
  146. MyFree(QueueNode);
  147. clean0:
  148. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  149. return(FALSE);
  150. }
  151. #ifdef UNICODE
  152. //
  153. // ANSI version
  154. //
  155. BOOL
  156. SetupQueueDeleteA(
  157. IN HSPFILEQ QueueHandle,
  158. IN PCSTR PathPart1,
  159. IN PCSTR PathPart2 OPTIONAL
  160. )
  161. {
  162. PWSTR p1,p2;
  163. DWORD d;
  164. BOOL b;
  165. b = FALSE;
  166. d = pSetupCaptureAndConvertAnsiArg(PathPart1,&p1);
  167. if(d == NO_ERROR) {
  168. if(PathPart2) {
  169. d = pSetupCaptureAndConvertAnsiArg(PathPart2,&p2);
  170. } else {
  171. p2 = NULL;
  172. }
  173. if(d == NO_ERROR) {
  174. b = _SetupQueueDelete(QueueHandle,p1,p2,0);
  175. d = GetLastError();
  176. if(p2) {
  177. MyFree(p2);
  178. }
  179. }
  180. MyFree(p1);
  181. }
  182. SetLastError(d);
  183. return(b);
  184. }
  185. #else
  186. //
  187. // Unicode stub
  188. //
  189. BOOL
  190. SetupQueueDeleteW(
  191. IN HSPFILEQ QueueHandle,
  192. IN PCWSTR PathPart1,
  193. IN PCWSTR PathPart2 OPTIONAL
  194. )
  195. {
  196. UNREFERENCED_PARAMETER(QueueHandle);
  197. UNREFERENCED_PARAMETER(PathPart1);
  198. UNREFERENCED_PARAMETER(PathPart2);
  199. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  200. return(FALSE);
  201. }
  202. #endif
  203. BOOL
  204. SetupQueueDelete(
  205. IN HSPFILEQ QueueHandle,
  206. IN PCTSTR PathPart1,
  207. IN PCTSTR PathPart2 OPTIONAL
  208. )
  209. /*++
  210. Routine Description:
  211. Place a delete operation on a setup file queue.
  212. Note that delete operations are assumed to be on fixed media.
  213. No prompting will be performed for delete operations when the
  214. queue is committed.
  215. Arguments:
  216. QueueHandle - supplies a handle to a setup file queue, as returned
  217. by SetupOpenFileQueue.
  218. PathPart1 - Supplies the first part of the path of
  219. the file to be deleted. If PathPart2 is not specified, then
  220. this is the full path of the file to be deleted.
  221. PathPart2 - if specified, supplies the second part of the path
  222. of the file to be deleted. This is concatenated to PathPart1
  223. to form the full pathname.
  224. Return Value:
  225. Boolean value indicating outcome. If FALSE, GetLastError() returns
  226. extended error information.
  227. --*/
  228. {
  229. PTSTR p1,p2;
  230. DWORD d;
  231. BOOL b;
  232. b = FALSE;
  233. d = CaptureStringArg(PathPart1,&p1);
  234. if(d == NO_ERROR) {
  235. if(PathPart2) {
  236. d = CaptureStringArg(PathPart2,&p2);
  237. } else {
  238. p2 = NULL;
  239. }
  240. if(d == NO_ERROR) {
  241. b = _SetupQueueDelete(QueueHandle,p1,p2,0);
  242. d = GetLastError();
  243. if(p2) {
  244. MyFree(p2);
  245. }
  246. }
  247. MyFree(p1);
  248. }
  249. SetLastError(d);
  250. return(b);
  251. }
  252. #ifdef UNICODE
  253. //
  254. // ANSI version
  255. //
  256. BOOL
  257. SetupQueueDeleteSectionA(
  258. IN HSPFILEQ QueueHandle,
  259. IN HINF InfHandle,
  260. IN HINF ListInfHandle, OPTIONAL
  261. IN PCSTR Section
  262. )
  263. {
  264. PWSTR section;
  265. DWORD d;
  266. BOOL b;
  267. d = pSetupCaptureAndConvertAnsiArg(Section,&section);
  268. if(d == NO_ERROR) {
  269. b = SetupQueueDeleteSectionW(QueueHandle,InfHandle,ListInfHandle,section);
  270. d = GetLastError();
  271. MyFree(section);
  272. } else {
  273. b = FALSE;
  274. }
  275. SetLastError(d);
  276. return(b);
  277. }
  278. #else
  279. //
  280. // Unicode stub
  281. //
  282. BOOL
  283. SetupQueueDeleteSectionW(
  284. IN HSPFILEQ QueueHandle,
  285. IN HINF InfHandle,
  286. IN HINF ListInfHandle, OPTIONAL
  287. IN PCWSTR Section
  288. )
  289. {
  290. UNREFERENCED_PARAMETER(QueueHandle);
  291. UNREFERENCED_PARAMETER(InfHandle);
  292. UNREFERENCED_PARAMETER(ListInfHandle);
  293. UNREFERENCED_PARAMETER(Section);
  294. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  295. return(FALSE);
  296. }
  297. #endif
  298. BOOL
  299. SetupQueueDeleteSection(
  300. IN HSPFILEQ QueueHandle,
  301. IN HINF InfHandle,
  302. IN HINF ListInfHandle, OPTIONAL
  303. IN PCTSTR Section
  304. )
  305. /*++
  306. Routine Description:
  307. Queue an entire section in an inf file for delete. The section must be
  308. in delete-section format and the inf file must contain [DestinationDirs].
  309. Arguments:
  310. QueueHandle - supplies a handle to a setup file queue, as returned
  311. by SetupOpenFileQueue.
  312. InfHandle - supplies a handle to an open inf file, that contains the
  313. [DestinationDirs] section.
  314. ListInfHandle - if specified, supplies a handle to the open inf file
  315. containing the section named by Section. If not specified this
  316. section is assumed to be in InfHandle.
  317. Section - supplies the name of the section to be queued for delete.
  318. Return Value:
  319. Boolean value indicating outcome. If FALSE, GetLastError() returns
  320. extended error information. Some files may have been queued successfully.
  321. --*/
  322. {
  323. BOOL b;
  324. PTSTR TargetDirectory;
  325. PCTSTR TargetFilename;
  326. INFCONTEXT LineContext;
  327. DWORD SizeRequired;
  328. DWORD rc;
  329. UINT Flags;
  330. if(!ListInfHandle) {
  331. ListInfHandle = InfHandle;
  332. }
  333. //
  334. // The section has to exist and there sas to be at least one line in it.
  335. //
  336. b = SetupFindFirstLine(ListInfHandle,Section,NULL,&LineContext);
  337. if(!b) {
  338. rc = GetLastError();
  339. pSetupLogSectionError(ListInfHandle,NULL,NULL,QueueHandle,Section,MSG_LOG_NOSECTION_DELETE,rc,NULL);
  340. SetLastError(ERROR_SECTION_NOT_FOUND); // this is not the real error, but might be what caller expects
  341. return(FALSE);
  342. }
  343. //
  344. // Iterate every line in the section.
  345. //
  346. do {
  347. //
  348. // Get the target filename out of the line.
  349. //
  350. TargetFilename = pSetupFilenameFromLine(&LineContext,FALSE);
  351. if(!TargetFilename) {
  352. SetLastError(ERROR_INVALID_DATA);
  353. return(FALSE);
  354. }
  355. //
  356. // Determine the target path for the file.
  357. //
  358. b = SetupGetTargetPath(InfHandle,&LineContext,NULL,NULL,0,&SizeRequired);
  359. if(!b) {
  360. return(FALSE);
  361. }
  362. TargetDirectory = MyMalloc(SizeRequired*sizeof(TCHAR));
  363. if(!TargetDirectory) {
  364. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  365. return(FALSE);
  366. }
  367. SetupGetTargetPath(InfHandle,&LineContext,NULL,TargetDirectory,SizeRequired,NULL);
  368. //
  369. // If present flags are field 4
  370. //
  371. if(!SetupGetIntField(&LineContext,4,(PINT)&Flags)) {
  372. Flags = 0;
  373. }
  374. //
  375. // Add to queue.
  376. //
  377. b = _SetupQueueDelete(QueueHandle,TargetDirectory,TargetFilename,Flags);
  378. rc = GetLastError();
  379. MyFree(TargetDirectory);
  380. if(!b) {
  381. SetLastError(rc);
  382. return(FALSE);
  383. }
  384. } while(SetupFindNextLine(&LineContext,&LineContext));
  385. return(TRUE);
  386. }
  387. #ifdef UNICODE
  388. //
  389. // ANSI version
  390. //
  391. BOOL
  392. SetupQueueRenameA(
  393. IN HSPFILEQ QueueHandle,
  394. IN PCSTR SourcePath,
  395. IN PCSTR SourceFilename, OPTIONAL
  396. IN PCSTR TargetPath, OPTIONAL
  397. IN PCSTR TargetFilename
  398. )
  399. {
  400. PWSTR sourcepath = NULL;
  401. PWSTR sourcefilename = NULL;
  402. PWSTR targetpath = NULL;
  403. PWSTR targetfilename = NULL;
  404. DWORD d;
  405. BOOL b;
  406. b = FALSE;
  407. d = pSetupCaptureAndConvertAnsiArg(SourcePath,&sourcepath);
  408. if((d == NO_ERROR) && SourceFilename) {
  409. d = pSetupCaptureAndConvertAnsiArg(SourceFilename,&sourcefilename);
  410. }
  411. if((d == NO_ERROR) && TargetPath) {
  412. d = pSetupCaptureAndConvertAnsiArg(TargetPath,&targetpath);
  413. }
  414. if(d == NO_ERROR) {
  415. d = pSetupCaptureAndConvertAnsiArg(TargetFilename,&targetfilename);
  416. }
  417. if(d == NO_ERROR) {
  418. b = SetupQueueRenameW(QueueHandle,sourcepath,sourcefilename,targetpath,targetfilename);
  419. d = GetLastError();
  420. }
  421. if(sourcepath) {
  422. MyFree(sourcepath);
  423. }
  424. if(sourcefilename) {
  425. MyFree(sourcefilename);
  426. }
  427. if(targetpath) {
  428. MyFree(targetpath);
  429. }
  430. if(targetfilename) {
  431. MyFree(targetfilename);
  432. }
  433. SetLastError(d);
  434. return(b);
  435. }
  436. #else
  437. //
  438. // Unicode stub
  439. //
  440. BOOL
  441. SetupQueueRenameW(
  442. IN HSPFILEQ QueueHandle,
  443. IN PCWSTR SourcePath,
  444. IN PCWSTR SourceFilename, OPTIONAL
  445. IN PCWSTR TargetPath, OPTIONAL
  446. IN PCWSTR TargetFilename
  447. )
  448. {
  449. UNREFERENCED_PARAMETER(QueueHandle);
  450. UNREFERENCED_PARAMETER(SourcePath);
  451. UNREFERENCED_PARAMETER(SourceFilename);
  452. UNREFERENCED_PARAMETER(TargetPath);
  453. UNREFERENCED_PARAMETER(TargetFilename);
  454. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  455. return(FALSE);
  456. }
  457. #endif
  458. BOOL
  459. SetupQueueRename(
  460. IN HSPFILEQ QueueHandle,
  461. IN PCTSTR SourcePath,
  462. IN PCTSTR SourceFilename, OPTIONAL
  463. IN PCTSTR TargetPath, OPTIONAL
  464. IN PCTSTR TargetFilename
  465. )
  466. /*++
  467. Routine Description:
  468. Place a rename operation on a setup file queue.
  469. Note that rename operations are assumed to be on fixed media.
  470. No prompting will be performed for rename operations when the
  471. queue is committed.
  472. Arguments:
  473. QueueHandle - supplies a handle to a setup file queue, as returned
  474. by SetupOpenFileQueue.
  475. SourcePath - Supplies the source path of the file to be renamed.
  476. If SourceFilename is specified, this is the part part only.
  477. If SourceFilename is not specified, this is the fully-qualified
  478. path.
  479. SourceFilename - if specified, supplies the filename part of the
  480. file to be renamed. If not specified, SourcePath is the fully-
  481. qualified path of the file to be renamed.
  482. TargetPath - if specified, supplies the target directory, and the rename
  483. is actually a move operation. If not specified, then the rename
  484. takes place without moving the file.
  485. TargetFilename - supplies the new name (no path) of the file.
  486. Return Value:
  487. Boolean value indicating outcome. If FALSE, GetLastError() returns
  488. extended error information.
  489. --*/
  490. {
  491. PSP_FILE_QUEUE Queue;
  492. PSP_FILE_QUEUE_NODE QueueNode, TempNode, PrevQueueNode;
  493. DWORD err = NO_ERROR;
  494. //
  495. // validate parameters so that we return correct error
  496. //
  497. if(SourcePath == NULL || TargetFilename == NULL) {
  498. err = ERROR_INVALID_PARAMETER;
  499. goto clean0;
  500. }
  501. Queue = (PSP_FILE_QUEUE)QueueHandle;
  502. //
  503. // Allocate a queue structure.
  504. //
  505. QueueNode = MyMalloc(sizeof(SP_FILE_QUEUE_NODE));
  506. if(!QueueNode) {
  507. err = ERROR_NOT_ENOUGH_MEMORY;
  508. goto clean0;
  509. }
  510. ZeroMemory(QueueNode, sizeof(SP_FILE_QUEUE_NODE));
  511. //
  512. // Operation is rename.
  513. //
  514. QueueNode->Operation = FILEOP_RENAME;
  515. //
  516. // Initialize unused SourceRootPath field.
  517. //
  518. QueueNode->SourceRootPath = -1;
  519. //
  520. // NOTE: When adding the following strings to the string table, we cast away
  521. // their CONST-ness to avoid a compiler warning. Since we are adding them
  522. // case-sensitively, we are guaranteed they will not be modified.
  523. //
  524. //
  525. // Set up the source path.
  526. //
  527. QueueNode->SourcePath = pSetupStringTableAddString(Queue->StringTable,
  528. (PTSTR)SourcePath,
  529. STRTAB_CASE_SENSITIVE
  530. );
  531. if(QueueNode->SourcePath == -1) {
  532. err = ERROR_NOT_ENOUGH_MEMORY;
  533. goto clean1;
  534. }
  535. //
  536. // Set up the source filename.
  537. //
  538. if(SourceFilename) {
  539. QueueNode->SourceFilename = pSetupStringTableAddString(Queue->StringTable,
  540. (PTSTR)SourceFilename,
  541. STRTAB_CASE_SENSITIVE
  542. );
  543. if(QueueNode->SourceFilename == -1) {
  544. err = ERROR_NOT_ENOUGH_MEMORY;
  545. goto clean1;
  546. }
  547. } else {
  548. QueueNode->SourceFilename = -1;
  549. }
  550. //
  551. // Set up the target directory.
  552. //
  553. if(TargetPath) {
  554. QueueNode->TargetDirectory = pSetupStringTableAddString(Queue->StringTable,
  555. (PTSTR)TargetPath,
  556. STRTAB_CASE_SENSITIVE
  557. );
  558. if(QueueNode->TargetDirectory == -1) {
  559. err = ERROR_NOT_ENOUGH_MEMORY;
  560. goto clean1;
  561. }
  562. } else {
  563. QueueNode->TargetDirectory = -1;
  564. }
  565. //
  566. // Set up the target filename.
  567. //
  568. QueueNode->TargetFilename = pSetupStringTableAddString(Queue->StringTable,
  569. (PTSTR)TargetFilename,
  570. STRTAB_CASE_SENSITIVE
  571. );
  572. if(QueueNode->TargetFilename == -1) {
  573. err = ERROR_NOT_ENOUGH_MEMORY;
  574. goto clean1;
  575. }
  576. //
  577. // Link the node onto the end of the rename queue.
  578. //
  579. QueueNode->Next = NULL;
  580. if(Queue->RenameQueue) {
  581. //
  582. // Check to see if this same rename operation has already been enqueued,
  583. // and if so, get rid of the new one, to avoid duplicates. NOTE: We
  584. // don't check the "InternalFlags" field, since if the node already
  585. // exists in the queue (based on all the other relevant fields comparing
  586. // successfully), then any internal flags that were set on the
  587. // previously-existing node should be preserved (i.e., our new node
  588. // always is created with InternalFlags set to zero).
  589. //
  590. for(TempNode=Queue->RenameQueue, PrevQueueNode = NULL;
  591. TempNode;
  592. PrevQueueNode = TempNode, TempNode=TempNode->Next) {
  593. if((TempNode->SourcePath == QueueNode->SourcePath) &&
  594. (TempNode->SourceFilename == QueueNode->SourceFilename) &&
  595. (TempNode->TargetDirectory == QueueNode->TargetDirectory) &&
  596. (TempNode->TargetFilename == QueueNode->TargetFilename)) {
  597. //
  598. // We have a duplicate--kill the newly-created queue node and
  599. // return success.
  600. //
  601. MYASSERT(TempNode->StyleFlags == 0);
  602. MyFree(QueueNode);
  603. return TRUE;
  604. }
  605. }
  606. MYASSERT(PrevQueueNode);
  607. PrevQueueNode->Next = QueueNode;
  608. } else {
  609. Queue->RenameQueue = QueueNode;
  610. }
  611. Queue->RenameNodeCount++;
  612. return(TRUE);
  613. clean1:
  614. MyFree(QueueNode);
  615. clean0:
  616. SetLastError(err);
  617. return(FALSE);
  618. }
  619. #ifdef UNICODE
  620. //
  621. // ANSI version
  622. //
  623. BOOL
  624. SetupQueueRenameSectionA(
  625. IN HSPFILEQ QueueHandle,
  626. IN HINF InfHandle,
  627. IN HINF ListInfHandle, OPTIONAL
  628. IN PCSTR Section
  629. )
  630. {
  631. PWSTR section;
  632. DWORD d;
  633. BOOL b;
  634. d = pSetupCaptureAndConvertAnsiArg(Section,&section);
  635. if(d == NO_ERROR) {
  636. b = SetupQueueRenameSectionW(QueueHandle,InfHandle,ListInfHandle,section);
  637. d = GetLastError();
  638. MyFree(section);
  639. } else {
  640. b = FALSE;
  641. }
  642. SetLastError(d);
  643. return(b);
  644. }
  645. #else
  646. //
  647. // Unicode stub
  648. //
  649. BOOL
  650. SetupQueueRenameSectionW(
  651. IN HSPFILEQ QueueHandle,
  652. IN HINF InfHandle,
  653. IN HINF ListInfHandle, OPTIONAL
  654. IN PCWSTR Section
  655. )
  656. {
  657. UNREFERENCED_PARAMETER(QueueHandle);
  658. UNREFERENCED_PARAMETER(InfHandle);
  659. UNREFERENCED_PARAMETER(ListInfHandle);
  660. UNREFERENCED_PARAMETER(Section);
  661. SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  662. return(FALSE);
  663. }
  664. #endif
  665. BOOL
  666. SetupQueueRenameSection(
  667. IN HSPFILEQ QueueHandle,
  668. IN HINF InfHandle,
  669. IN HINF ListInfHandle, OPTIONAL
  670. IN PCTSTR Section
  671. )
  672. /*++
  673. Routine Description:
  674. Queue an entire section in an inf file for delete. The section must be
  675. in delete-section format and the inf file must contain [DestinationDirs].
  676. The format of a rename list section dictates that only renames within the
  677. same directory is supported (ie, you cannot queue file moves with this API).
  678. Arguments:
  679. QueueHandle - supplies a handle to a setup file queue, as returned
  680. by SetupOpenFileQueue.
  681. InfHandle - supplies a handle to an open inf file, that contains the
  682. [DestinationDirs] section.
  683. ListInfHandle - if specified, supplies a handle to the open inf file
  684. containing the section named by Section. If not specified this
  685. section is assumed to be in InfHandle.
  686. Section - supplies the name of the section to be queued for delete.
  687. Return Value:
  688. Boolean value indicating outcome. If FALSE, GetLastError() returns
  689. extended error information.
  690. --*/
  691. {
  692. BOOL b;
  693. INFCONTEXT LineContext;
  694. PCTSTR TargetFilename;
  695. PCTSTR SourceFilename;
  696. PTSTR Directory;
  697. DWORD SizeRequired;
  698. DWORD rc;
  699. if(!ListInfHandle) {
  700. ListInfHandle = InfHandle;
  701. }
  702. //
  703. // The section has to exist and there has to be at least one line in it.
  704. //
  705. b = SetupFindFirstLine(ListInfHandle,Section,NULL,&LineContext);
  706. if(!b) {
  707. rc = GetLastError();
  708. pSetupLogSectionError(ListInfHandle,NULL,NULL,QueueHandle,Section,MSG_LOG_NOSECTION_RENAME,rc,NULL);
  709. SetLastError(ERROR_SECTION_NOT_FOUND); // this is not the real error, but might be what caller expects
  710. return(FALSE);
  711. }
  712. //
  713. // Iterate every line in the section.
  714. //
  715. do {
  716. //
  717. // Get the target filename out of the line.
  718. //
  719. TargetFilename = pSetupFilenameFromLine(&LineContext,FALSE);
  720. if(!TargetFilename) {
  721. SetLastError(ERROR_INVALID_DATA);
  722. return(FALSE);
  723. }
  724. //
  725. // Get source filename out of the line.
  726. //
  727. SourceFilename = pSetupFilenameFromLine(&LineContext,TRUE);
  728. if(!SourceFilename || (*SourceFilename == 0)) {
  729. SetLastError(ERROR_INVALID_DATA);
  730. return(FALSE);
  731. }
  732. //
  733. // Determine the path of the file.
  734. //
  735. b = SetupGetTargetPath(InfHandle,&LineContext,NULL,NULL,0,&SizeRequired);
  736. if(!b) {
  737. return(FALSE);
  738. }
  739. Directory = MyMalloc(SizeRequired*sizeof(TCHAR));
  740. if(!Directory) {
  741. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  742. return(FALSE);
  743. }
  744. SetupGetTargetPath(InfHandle,&LineContext,NULL,Directory,SizeRequired,NULL);
  745. //
  746. // Add to queue.
  747. //
  748. b = SetupQueueRename(
  749. QueueHandle,
  750. Directory,
  751. SourceFilename,
  752. NULL,
  753. TargetFilename
  754. );
  755. rc = GetLastError();
  756. MyFree(Directory);
  757. if(!b) {
  758. SetLastError(rc);
  759. return(FALSE);
  760. }
  761. } while(SetupFindNextLine(&LineContext,&LineContext));
  762. return(TRUE);
  763. }