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.

1622 lines
51 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2001, Microsoft Corporation All rights reserved.
  4. //
  5. // Module Name:
  6. //
  7. // infparser.cpp
  8. //
  9. // Abstract:
  10. //
  11. // This file contains the entry point of the infparser.exe utility.
  12. //
  13. // Revision History:
  14. //
  15. // 2001-06-20 lguindon Created.
  16. //
  17. ///////////////////////////////////////////////////////////////////////////////
  18. ///////////////////////////////////////////////////////////////////////////////
  19. //
  20. // Includes Files.
  21. //
  22. ///////////////////////////////////////////////////////////////////////////////
  23. #include "stdafx.h"
  24. #include "infparser.h"
  25. ///////////////////////////////////////////////////////////////////////////////
  26. //
  27. // Global variable.
  28. //
  29. ///////////////////////////////////////////////////////////////////////////////
  30. BOOL bSilence = TRUE;
  31. DWORD dwComponentCounter = 0;
  32. DWORD dwDirectoryCounter = 1;
  33. WORD gBuildNumber = 0;
  34. ///////////////////////////////////////////////////////////////////////////////
  35. //
  36. // Prototypes.
  37. //
  38. ///////////////////////////////////////////////////////////////////////////////
  39. BOOL DirectoryExist(LPSTR dirPath);
  40. BOOL ValidateLanguage(LPSTR dirPath, LPSTR langName, DWORD binType);
  41. WORD ConvertLanguage(LPSTR dirPath, LPSTR langName);
  42. int ListContents(LPSTR filename, LPSTR dirPath, LPSTR lang, DWORD flavor, DWORD binType);
  43. int ListComponents(FileList *dirList, LPSTR dirPath, LPSTR lang, DWORD flavor, DWORD binType);
  44. int ListMuiFiles(FileList *dirList, LPSTR dirPath, LPSTR lang, DWORD flavor, DWORD binType);
  45. void PrintFileList(FileList* list, HANDLE hFile, BOOL compressed, BOOL bWinDir);
  46. BOOL PrintLine(HANDLE hFile, LPCSTR lpLine);
  47. HANDLE CreateOutputFile(LPSTR filename);
  48. VOID removeSpace(LPSTR src, LPSTR dest);
  49. DWORD TransNum(LPTSTR lpsz);
  50. void Usage();
  51. ///////////////////////////////////////////////////////////////////////////////
  52. //
  53. // Main entry point.
  54. //
  55. ///////////////////////////////////////////////////////////////////////////////
  56. int __cdecl main(int argc, char* argv[])
  57. {
  58. LPSTR sLangName = NULL;
  59. LPSTR sDirPath = NULL;
  60. DWORD dwFlavor = FLV_UNDEFINED;
  61. DWORD dwBinType = BIN_UNDEFINED;
  62. DWORD dwArg = ARG_UNDEFINED;
  63. WORD wLangID = 0;
  64. HANDLE hFile;
  65. int argIndex = 1;
  66. LPSTR lpFileName = NULL;
  67. //
  68. // Check if we have the minimal number of arguments.
  69. //
  70. if (argc < 6)
  71. {
  72. Usage();
  73. return (-1);
  74. }
  75. //
  76. // Parse the command line.
  77. //
  78. while (argIndex < argc)
  79. {
  80. if (*argv[argIndex] == '/')
  81. {
  82. switch(*(argv[argIndex]+1))
  83. {
  84. case('b'):
  85. case('B'):
  86. {
  87. //
  88. // Binairy i386 or ia64
  89. //
  90. if ((*(argv[argIndex]+3) == '3') && (*(argv[argIndex]+4) == '2'))
  91. {
  92. dwBinType = BIN_32;
  93. }
  94. else if ((*(argv[argIndex]+3) == '6') && (*(argv[argIndex]+4) == '4'))
  95. {
  96. dwBinType = BIN_64;
  97. }
  98. else
  99. {
  100. return (argIndex);
  101. }
  102. dwArg |= ARG_BINARY;
  103. break;
  104. }
  105. case('l'):
  106. case('L'):
  107. {
  108. //
  109. // Language
  110. //
  111. sLangName = (argv[argIndex]+3);
  112. dwArg |= ARG_LANG;
  113. break;
  114. }
  115. case('f'):
  116. case('F'):
  117. {
  118. //
  119. // Flavor requested
  120. //
  121. switch(*(argv[argIndex]+3))
  122. {
  123. case('c'):
  124. case('C'):
  125. {
  126. dwFlavor = FLV_CORE;
  127. break;
  128. }
  129. case('p'):
  130. case('P'):
  131. {
  132. dwFlavor = FLV_PROFESSIONAL;
  133. break;
  134. }
  135. case('s'):
  136. case('S'):
  137. {
  138. dwFlavor = FLV_SERVER;
  139. break;
  140. }
  141. case('a'):
  142. case('A'):
  143. {
  144. dwFlavor = FLV_ADVSERVER;
  145. break;
  146. }
  147. case('d'):
  148. case('D'):
  149. {
  150. dwFlavor = FLV_DATACENTER;
  151. break;
  152. }
  153. default:
  154. {
  155. return (argIndex);
  156. }
  157. }
  158. dwArg |= ARG_FLAVOR;
  159. break;
  160. }
  161. case('s'):
  162. case('S'):
  163. {
  164. //
  165. // Binairy location
  166. //
  167. sDirPath = (argv[argIndex]+3);
  168. dwArg |= ARG_DIR;
  169. break;
  170. }
  171. case('o'):
  172. case('O'):
  173. {
  174. //
  175. // Output filename
  176. //
  177. /*
  178. if ((hFile = CreateOutputFile(argv[argIndex]+3)) == INVALID_HANDLE_VALUE)
  179. {
  180. return (argIndex);
  181. }
  182. */
  183. lpFileName = argv[argIndex]+3;
  184. dwArg |= ARG_OUT;
  185. break;
  186. }
  187. case('v'):
  188. case('V'):
  189. {
  190. //
  191. // Verbose mode
  192. //
  193. bSilence = FALSE;
  194. dwArg |= ARG_SILENT;
  195. break;
  196. }
  197. default:
  198. {
  199. Usage();
  200. return (argIndex);
  201. }
  202. }
  203. }
  204. else
  205. {
  206. Usage();
  207. return (-1);
  208. }
  209. //
  210. // Next argument
  211. //
  212. argIndex++;
  213. }
  214. //
  215. // Validate arguments passed. Should have all five basic argument in order
  216. // to continue.
  217. //
  218. if ((dwArg == ARG_UNDEFINED) ||
  219. !((dwArg & ARG_BINARY) &&
  220. (dwArg & ARG_LANG) &&
  221. (dwArg & ARG_DIR) &&
  222. (dwArg & ARG_OUT) &&
  223. (dwArg & ARG_FLAVOR)))
  224. {
  225. Usage();
  226. return (-1);
  227. }
  228. //
  229. // Validate Source directory
  230. //
  231. if (!DirectoryExist(sDirPath))
  232. {
  233. return (-2);
  234. }
  235. //
  236. // Validate Language
  237. //
  238. if (!ValidateLanguage(sDirPath, sLangName, dwBinType))
  239. {
  240. return (-3);
  241. }
  242. //
  243. // Get LANGID from the language
  244. //
  245. if ( (gBuildNumber = ConvertLanguage(sDirPath, sLangName)) == 0x0000)
  246. {
  247. return (-4);
  248. }
  249. //
  250. // Generate the file list
  251. //
  252. if ((dwArg & ARG_OUT) && lpFileName)
  253. {
  254. return ListContents(lpFileName, sDirPath, sLangName, dwFlavor, dwBinType);
  255. }
  256. }
  257. ///////////////////////////////////////////////////////////////////////////////
  258. //
  259. // ListContents()
  260. //
  261. // Generate the file list contents.
  262. //
  263. ///////////////////////////////////////////////////////////////////////////////
  264. int ListContents(LPSTR filename, LPSTR dirPath, LPSTR lang, DWORD flavor, DWORD binType)
  265. {
  266. int iRet = 0;
  267. Uuid* uuid;
  268. CHAR schemaPath[MAX_PATH] = {0};
  269. CHAR outputString[4096] = {0};
  270. FileList fileList;
  271. HANDLE outputFile = CreateOutputFile(filename);
  272. if (outputFile == INVALID_HANDLE_VALUE)
  273. {
  274. iRet = -1;
  275. goto ListContents_EXIT;
  276. }
  277. //
  278. // Create a UUID for this module and the schema path
  279. //
  280. uuid = new Uuid();
  281. sprintf(schemaPath, "%s\\control\\MmSchema.xml", dirPath);
  282. //
  283. // Print module header.
  284. //
  285. PrintLine(outputFile, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>");
  286. sprintf(outputString, "<Module Name=\"MUI MSI File Content\" Id=\"%s\" Language=\"0\" Version=\"1.0\" xmlns=\"%s\">", uuid->getString(), schemaPath);
  287. PrintLine(outputFile, outputString);
  288. delete uuid;
  289. uuid = new Uuid();
  290. sprintf(outputString, " <Package Id=\"%s\"", uuid->getString());
  291. PrintLine(outputFile, outputString);
  292. delete uuid;
  293. PrintLine(outputFile, " Description=\"Content module\"");
  294. PrintLine(outputFile, " Platforms=\"Intel\"");
  295. PrintLine(outputFile, " Languages=\"0\"");
  296. PrintLine(outputFile, " InstallerVersion=\"100\"");
  297. PrintLine(outputFile, " Manufacturer=\"Microsoft Corporation\"");
  298. PrintLine(outputFile, " Keywords=\"MergeModule, MSI, Database\"");
  299. PrintLine(outputFile, " Comments=\"This merge module contains all the MUI file content\"");
  300. PrintLine(outputFile, " ShortNames=\"yes\" Compressed=\"yes\"");
  301. PrintLine(outputFile, "/>");
  302. //
  303. // Generate components file list
  304. //
  305. if ( (iRet = ListComponents(&fileList, dirPath, lang, flavor, binType)) != 0)
  306. {
  307. goto ListContents_EXIT;
  308. }
  309. //
  310. // Generate Mui file list
  311. //
  312. if ((iRet =ListMuiFiles(&fileList, dirPath, lang, flavor, binType)) != 0)
  313. {
  314. goto ListContents_EXIT;
  315. }
  316. //
  317. // Print compressed directory structure.
  318. //
  319. PrintLine(outputFile, "<Directory Name=\"SOURCEDIR\">TARGETDIR");
  320. if (fileList.isDirId(TRUE))
  321. {
  322. PrintLine(outputFile, " <Directory Name=\"Windows\">WindowsFolder");
  323. PrintFileList(&fileList, outputFile, TRUE, TRUE);
  324. PrintLine(outputFile, " </Directory>");
  325. }
  326. if (fileList.isDirId(FALSE))
  327. {
  328. PrintLine(outputFile, " <Directory Name=\"ProgramFilesFolder\">ProgramFilesFolder");
  329. PrintFileList(&fileList, outputFile, TRUE, FALSE);
  330. PrintLine(outputFile, " </Directory>");
  331. }
  332. PrintLine(outputFile, "</Directory>");
  333. //
  334. // Print module footer.
  335. //
  336. PrintLine(outputFile, "</Module>");
  337. ListContents_EXIT:
  338. if (outputFile)
  339. CloseHandle(outputFile);
  340. return (iRet);
  341. }
  342. ///////////////////////////////////////////////////////////////////////////////
  343. //
  344. // ListComponents()
  345. //
  346. // Generate the file list of each components.
  347. //
  348. ///////////////////////////////////////////////////////////////////////////////
  349. int ListComponents(FileList *dirList, LPSTR dirPath, LPSTR lang, DWORD flavor, DWORD binType)
  350. {
  351. HINF hFile;
  352. CHAR muiFilePath[MAX_PATH];
  353. UINT lineCount, lineNum;
  354. INFCONTEXT context;
  355. ComponentList componentList;
  356. Component* component;
  357. //
  358. // Used only in core flavor
  359. //
  360. if (flavor != FLV_CORE)
  361. {
  362. return (0);
  363. }
  364. //
  365. // Create the path to open the mui.inf file
  366. //
  367. sprintf(muiFilePath, "%s\\mui.inf", dirPath);
  368. //
  369. // Open the MUI.INF file.
  370. //
  371. hFile = SetupOpenInfFile(muiFilePath, NULL, INF_STYLE_WIN4, NULL);
  372. if (hFile == INVALID_HANDLE_VALUE)
  373. {
  374. return (-1);
  375. }
  376. //
  377. // Get the number of component.
  378. //
  379. lineCount = (UINT)SetupGetLineCount(hFile, TEXT("Components"));
  380. if (lineCount > 0)
  381. {
  382. //
  383. // Go through all component of the list.
  384. //
  385. CHAR componentName[MAX_PATH];
  386. CHAR componentFolder[MAX_PATH];
  387. CHAR componentInf[MAX_PATH];
  388. CHAR componentInst[MAX_PATH];
  389. for (lineNum = 0; lineNum < lineCount; lineNum++)
  390. {
  391. if (SetupGetLineByIndex(hFile, TEXT("Components"), lineNum, &context) &&
  392. SetupGetStringField(&context, 0, componentName, MAX_PATH, NULL) &&
  393. SetupGetStringField(&context, 1, componentFolder, MAX_PATH, NULL) &&
  394. SetupGetStringField(&context, 2, componentInf, MAX_PATH, NULL) &&
  395. SetupGetStringField(&context, 3, componentInst, MAX_PATH, NULL))
  396. {
  397. //
  398. // Create the components
  399. //
  400. if( (component = new Component( componentName,
  401. componentFolder,
  402. componentInf,
  403. componentInst)) != NULL)
  404. {
  405. componentList.add(component);
  406. }
  407. }
  408. }
  409. }
  410. //
  411. // Close inf handle
  412. //
  413. SetupCloseInfFile(hFile);
  414. //
  415. // Output component information
  416. //
  417. component = componentList.getFirst();
  418. while (component != NULL)
  419. {
  420. CHAR componentInfPath[MAX_PATH];
  421. CHAR componentPath[MAX_PATH];
  422. int fieldCount, fieldCount2;
  423. INFCONTEXT context2;
  424. INFCONTEXT context3;
  425. File* file;
  426. //
  427. // Compute the component inf path.
  428. //
  429. if (binType == BIN_32)
  430. {
  431. sprintf( componentInfPath,
  432. "%s\\%s\\i386.uncomp\\%s\\%s",
  433. dirPath,
  434. lang,
  435. component->getFolderName(),
  436. component->getInfName());
  437. sprintf( componentPath,
  438. "%s\\%s\\i386.uncomp\\%s",
  439. dirPath,
  440. lang,
  441. component->getFolderName());
  442. }
  443. else
  444. {
  445. sprintf( componentInfPath,
  446. "%s\\%s\\ia64.uncomp\\%s\\%s",
  447. dirPath,
  448. lang,
  449. component->getFolderName(),
  450. component->getInfName());
  451. sprintf( componentPath,
  452. "%s\\%s\\ai64.uncomp\\%s",
  453. dirPath,
  454. lang,
  455. component->getFolderName());
  456. }
  457. //
  458. // Open the component inf file.
  459. //
  460. hFile = SetupOpenInfFile(componentInfPath, NULL, INF_STYLE_WIN4, NULL);
  461. if (hFile == INVALID_HANDLE_VALUE)
  462. {
  463. return (-1);
  464. }
  465. //
  466. // Search for the CopyFiles section
  467. //
  468. if (SetupFindFirstLine( hFile,
  469. component->getInfInstallSectionName(),
  470. "CopyFiles",
  471. &context ) &&
  472. (fieldCount = SetupGetFieldCount(&context)))
  473. {
  474. CHAR instSectionName[MAX_PATH];
  475. INT destDirId;
  476. CHAR destDirSubFolder[MAX_PATH];
  477. CHAR destFileName[MAX_PATH];
  478. CHAR srcFileName[MAX_PATH];
  479. for (int fieldIdx = 1; fieldIdx <= fieldCount; fieldIdx++)
  480. {
  481. //
  482. // Get the install section Names and search for the
  483. // corresponding DestinationDirs.
  484. //
  485. if (SetupGetStringField(&context, fieldIdx, instSectionName, MAX_PATH, NULL) &&
  486. SetupFindFirstLine(hFile, "DestinationDirs", instSectionName, &context2))
  487. {
  488. //
  489. // Get the destination directory information for this
  490. // installation section
  491. //
  492. if (SetupGetIntField(&context2, 1, &destDirId))
  493. {
  494. //
  495. // Possible that no sub directory
  496. //
  497. if(!SetupGetStringField(&context2, 2, destDirSubFolder, MAX_PATH, NULL))
  498. {
  499. destDirSubFolder[0] = '\0';
  500. }
  501. //
  502. // Scan the section for file
  503. //
  504. if ((lineCount = (UINT)SetupGetLineCount(hFile, instSectionName)) > 0)
  505. {
  506. for (lineNum = 0; lineNum < lineCount; lineNum++)
  507. {
  508. if (SetupGetLineByIndex(hFile, instSectionName, lineNum, &context3) &&
  509. (fieldCount2 = SetupGetFieldCount(&context3)))
  510. {
  511. if (fieldCount2 > 1)
  512. {
  513. if (SetupGetStringField(&context3, 1, destFileName, MAX_PATH, NULL) &&
  514. SetupGetStringField(&context3, 2, srcFileName, MAX_PATH, NULL))
  515. {
  516. //
  517. // Create the components
  518. //
  519. if ((file = new File(destDirSubFolder,
  520. destFileName,
  521. componentPath,
  522. srcFileName,
  523. destDirId)) != NULL)
  524. {
  525. dirList->add(file);
  526. }
  527. }
  528. }
  529. else
  530. {
  531. if( SetupGetStringField(&context3, 0, destFileName, MAX_PATH, NULL))
  532. {
  533. //
  534. // Create the components
  535. //
  536. if( (file = new File(destDirSubFolder,
  537. destFileName,
  538. componentPath,
  539. destFileName,
  540. destDirId)) != NULL)
  541. {
  542. dirList->add(file);
  543. }
  544. }
  545. }
  546. }
  547. }
  548. }
  549. }
  550. }
  551. }
  552. }
  553. //
  554. // Next Component
  555. //
  556. component = component->getNext();
  557. }
  558. return 0;
  559. }
  560. ///////////////////////////////////////////////////////////////////////////////
  561. //
  562. // ListMuiFiles()
  563. //
  564. // Generate the file list for MUI.
  565. //
  566. ///////////////////////////////////////////////////////////////////////////////
  567. int ListMuiFiles(FileList *dirList, LPSTR dirPath, LPSTR lang, DWORD flavor, DWORD binType)
  568. {
  569. HINF hFile;
  570. CHAR muiFilePath[MAX_PATH];
  571. CHAR muiFileSearchPath[MAX_PATH];
  572. int lineCount, lineNum, fieldCount;
  573. INFCONTEXT context;
  574. FileLayoutExceptionList exceptionList;
  575. WIN32_FIND_DATA findData;
  576. HANDLE fileHandle;
  577. File* file;
  578. //
  579. // Create the path to open the mui.inf file
  580. //
  581. sprintf(muiFilePath, "%s\\mui.inf", dirPath);
  582. //
  583. // Open the MUI.INF file.
  584. //
  585. hFile = SetupOpenInfFile(muiFilePath, NULL, INF_STYLE_WIN4, NULL);
  586. if (hFile == INVALID_HANDLE_VALUE)
  587. {
  588. return (-1);
  589. }
  590. //
  591. // Get the number of file exception.
  592. //
  593. lineCount = (UINT)SetupGetLineCount(hFile, TEXT("File_Layout"));
  594. if (lineCount > 0)
  595. {
  596. //
  597. // Go through all file exception of the list.
  598. //
  599. CHAR originFilename[MAX_PATH];
  600. CHAR destFilename[MAX_PATH];
  601. CHAR fileFlavor[30];
  602. DWORD dwFlavor;
  603. for (lineNum = 0; lineNum < lineCount; lineNum++)
  604. {
  605. if (SetupGetLineByIndex(hFile, TEXT("File_Layout"), lineNum, &context) &&
  606. (fieldCount = SetupGetFieldCount(&context)))
  607. {
  608. if (SetupGetStringField(&context, 0, originFilename, MAX_PATH, NULL) &&
  609. SetupGetStringField(&context, 1, destFilename, MAX_PATH, NULL))
  610. {
  611. FileLayout* fileException;
  612. dwFlavor = 0;
  613. for(int fieldId = 2; fieldId <= fieldCount; fieldId++)
  614. {
  615. if(SetupGetStringField(&context, fieldId, fileFlavor, MAX_PATH, NULL))
  616. {
  617. switch(*fileFlavor)
  618. {
  619. case('p'):
  620. case('P'):
  621. {
  622. dwFlavor |= FLV_PROFESSIONAL;
  623. break;
  624. }
  625. case('s'):
  626. case('S'):
  627. {
  628. dwFlavor |= FLV_SERVER;
  629. break;
  630. }
  631. case('d'):
  632. case('D'):
  633. {
  634. dwFlavor |= FLV_DATACENTER;
  635. break;
  636. }
  637. case('a'):
  638. case('A'):
  639. {
  640. dwFlavor |= FLV_ENTERPRISE;
  641. break;
  642. }
  643. }
  644. }
  645. }
  646. //
  647. // Add only information needed for this specific flavor.
  648. //
  649. fileException = new FileLayout(originFilename, destFilename, dwFlavor);
  650. exceptionList.insert(fileException);
  651. }
  652. }
  653. }
  654. }
  655. //
  656. // Close inf handle
  657. //
  658. SetupCloseInfFile(hFile);
  659. //
  660. // Compute the binary source path.
  661. //
  662. if (binType == BIN_32)
  663. {
  664. sprintf( muiFileSearchPath, "%s\\%s\\i386.uncomp", dirPath, lang);
  665. sprintf( muiFilePath, "%s\\%s\\i386.uncomp\\*.*", dirPath, lang);
  666. }
  667. else
  668. {
  669. sprintf( muiFileSearchPath, "%s\\%s\\ia64.uncomp", dirPath, lang);
  670. sprintf( muiFilePath, "%s\\%s\\ia64.uncomp\\*.*", dirPath, lang);
  671. }
  672. //
  673. // Scan uncomp source directory for file information
  674. //
  675. if ((fileHandle = FindFirstFile(muiFilePath, &findData)) != INVALID_HANDLE_VALUE)
  676. {
  677. //
  678. // Look for files
  679. //
  680. do
  681. {
  682. LPSTR extensionPtr;
  683. INT dirIdentifier = 0;
  684. CHAR destDirectory[MAX_PATH] = {0};
  685. CHAR destName[MAX_PATH] = {0};
  686. FileLayout* fileException = NULL;
  687. //
  688. // Scan only files at this level.
  689. //
  690. if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
  691. {
  692. continue;
  693. }
  694. //
  695. // Search the extension to determine the destination location and possibly
  696. // exclude file destined for Personal.
  697. //
  698. if ((extensionPtr = strrchr(findData.cFileName, '.')) != NULL)
  699. {
  700. if( (_tcsicmp(extensionPtr, TEXT(".chm")) == 0) ||
  701. (_tcsicmp(extensionPtr, TEXT(".chq")) == 0) ||
  702. (_tcsicmp(extensionPtr, TEXT(".cnt")) == 0) ||
  703. (_tcsicmp(extensionPtr, TEXT(".hlp")) == 0))
  704. {
  705. dirIdentifier = 18;
  706. sprintf(destDirectory, "MUI\\%04x", gBuildNumber);
  707. }
  708. else if (_tcsicmp(extensionPtr, TEXT(".mfl")) == 0)
  709. {
  710. dirIdentifier = 11;
  711. sprintf(destDirectory, "wbem\\MUI\\%04x", gBuildNumber);
  712. }
  713. else if (_tcsicmp(findData.cFileName, TEXT("hhctrlui.dll")) == 0)
  714. {
  715. dirIdentifier = 11;
  716. sprintf(destDirectory, "MUI\\%04x", gBuildNumber);
  717. }
  718. else
  719. {
  720. dirIdentifier = 10;
  721. sprintf(destDirectory, "MUI\\FALLBACK\\%04x", gBuildNumber);
  722. }
  723. }
  724. //
  725. // Search for different destination name in the exception list.
  726. //
  727. if ((fileException = exceptionList.search(findData.cFileName)) != NULL )
  728. {
  729. //
  730. // Verify it's the needed flavor
  731. //
  732. if (fileException->isFlavor(flavor))
  733. {
  734. sprintf(destName, "%s", fileException->getDestFileName());
  735. }
  736. else
  737. {
  738. //
  739. // Skip the file. Not need in this flavor.
  740. //
  741. continue;
  742. }
  743. }
  744. else
  745. {
  746. if (((extensionPtr = strrchr(findData.cFileName, '.')) != NULL) &&
  747. ((*(extensionPtr-1) == 'P') || (*(extensionPtr-1) == 'p')))
  748. {
  749. continue;
  750. }
  751. else if (flavor != FLV_CORE)
  752. {
  753. continue;
  754. }
  755. else
  756. {
  757. sprintf(destName, "%s", findData.cFileName);
  758. }
  759. }
  760. //
  761. // Create a file
  762. //
  763. if (file = new File(destDirectory,
  764. destName,
  765. muiFileSearchPath,
  766. findData.cFileName,
  767. dirIdentifier))
  768. {
  769. dirList->add(file);
  770. }
  771. }
  772. while (FindNextFile(fileHandle, &findData));
  773. FindClose(fileHandle);
  774. }
  775. //
  776. // Add Specific MuiSetup files.
  777. //
  778. file = new File( TEXT("MUI"),
  779. TEXT("Muisetup.exe"),
  780. dirPath,
  781. TEXT("Muisetup.exe"),
  782. 10);
  783. dirList->add(file);
  784. file = new File( TEXT("MUI"),
  785. TEXT("Muisetup.hlp"),
  786. dirPath,
  787. TEXT("Muisetup.hlp"),
  788. 10);
  789. dirList->add(file);
  790. file = new File( TEXT("MUI"),
  791. TEXT("Eula.txt"),
  792. dirPath,
  793. TEXT("Eula.txt"),
  794. 10);
  795. dirList->add(file);
  796. file = new File( TEXT("MUI"),
  797. TEXT("Relnotes.txt"),
  798. dirPath,
  799. TEXT("Relnotes.txt"),
  800. 10);
  801. dirList->add(file);
  802. file = new File( TEXT("MUI"),
  803. TEXT("Readme.txt"),
  804. dirPath,
  805. TEXT("Readme.txt"),
  806. 10);
  807. dirList->add(file);
  808. file = new File( TEXT("MUI"),
  809. TEXT("Mui.inf"),
  810. dirPath,
  811. TEXT("Mui.inf"),
  812. 10);
  813. dirList->add(file);
  814. return 0;
  815. }
  816. ///////////////////////////////////////////////////////////////////////////////
  817. //
  818. // ValidateLanguage()
  819. //
  820. // Verify if the language given is valid and checks is the files are
  821. // available.
  822. //
  823. ///////////////////////////////////////////////////////////////////////////////
  824. BOOL ValidateLanguage(LPSTR dirPath, LPSTR langName, DWORD binType)
  825. {
  826. CHAR langPath[MAX_PATH] = {0};
  827. //
  828. // Check if the binary type in order to determine the right path.
  829. //
  830. if (binType == BIN_32)
  831. {
  832. sprintf(langPath, "%s\\%s\\i386.uncomp", dirPath, langName);
  833. }
  834. else
  835. {
  836. sprintf(langPath, "%s\\%s\\ia64.uncomp", dirPath, langName);
  837. }
  838. return (DirectoryExist(langPath));
  839. }
  840. ///////////////////////////////////////////////////////////////////////////////
  841. //
  842. // DirectoryExist()
  843. //
  844. // Verify if the given directory exists and contains files.
  845. //
  846. ///////////////////////////////////////////////////////////////////////////////
  847. BOOL DirectoryExist(LPSTR dirPath)
  848. {
  849. WIN32_FIND_DATA FindData;
  850. HANDLE FindHandle;
  851. //
  852. // Sanity check.
  853. //
  854. if (dirPath == NULL)
  855. {
  856. return FALSE;
  857. }
  858. //
  859. // See if the language group directory exists.
  860. //
  861. FindHandle = FindFirstFile(dirPath, &FindData);
  862. if (FindHandle != INVALID_HANDLE_VALUE)
  863. {
  864. FindClose(FindHandle);
  865. if (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
  866. {
  867. //
  868. // Return success.
  869. //
  870. return (TRUE);
  871. }
  872. }
  873. //
  874. // Return failure.
  875. //
  876. if (!bSilence)
  877. {
  878. printf("ERR[%s]: No files found in the directory.\n", dirPath);
  879. }
  880. return (FALSE);
  881. }
  882. ///////////////////////////////////////////////////////////////////////////////
  883. //
  884. // ConvertLanguage()
  885. //
  886. // Look into mui.inf file for the corresponding language identifier.
  887. //
  888. ///////////////////////////////////////////////////////////////////////////////
  889. WORD ConvertLanguage(LPSTR dirPath, LPSTR langName)
  890. {
  891. HINF hFile;
  892. CHAR muiFilePath[MAX_PATH];
  893. CHAR muiLang[30];
  894. UINT lineCount, lineNum;
  895. INFCONTEXT context;
  896. DWORD langId = 0x00000000;
  897. //
  898. // Create the path to open the mui.inf file
  899. //
  900. sprintf(muiFilePath, "%s\\mui.inf", dirPath);
  901. sprintf(muiLang, "%s.MUI", langName);
  902. //
  903. // Open the MUI.INF file.
  904. //
  905. hFile = SetupOpenInfFile(muiFilePath, NULL, INF_STYLE_WIN4, NULL);
  906. if (hFile == INVALID_HANDLE_VALUE)
  907. {
  908. return (0x0000);
  909. }
  910. //
  911. // Get the number of Language.
  912. //
  913. lineCount = (UINT)SetupGetLineCount(hFile, TEXT("Languages"));
  914. if (lineCount > 0)
  915. {
  916. //
  917. // Go through all language of the list to find a .
  918. //
  919. CHAR langID[MAX_PATH];
  920. CHAR name[MAX_PATH];
  921. for (lineNum = 0; lineNum < lineCount; lineNum++)
  922. {
  923. if (SetupGetLineByIndex(hFile, TEXT("Languages"), lineNum, &context) &&
  924. SetupGetStringField(&context, 0, langID, MAX_PATH, NULL) &&
  925. SetupGetStringField(&context, 1, name, MAX_PATH, NULL))
  926. {
  927. if ( _tcsicmp(name, muiLang) == 0)
  928. {
  929. langId = TransNum(langID);
  930. SetupCloseInfFile(hFile);
  931. return (WORD)(langId);
  932. }
  933. }
  934. }
  935. }
  936. //
  937. // Close inf handle
  938. //
  939. SetupCloseInfFile(hFile);
  940. return (0x0000);
  941. }
  942. ////////////////////////////////////////////////////////////////////////////
  943. //
  944. // PrintFileList
  945. //
  946. // Print a file list in XML format.
  947. //
  948. ////////////////////////////////////////////////////////////////////////////
  949. void PrintFileList(FileList* list, HANDLE hFile, BOOL compressed, BOOL bWinDir)
  950. {
  951. if (compressed)
  952. {
  953. File* item;
  954. CHAR itemDescription[4096];
  955. CHAR spaces[30];
  956. int j;
  957. item = list->getFirst();
  958. while (item != NULL)
  959. {
  960. LPSTR refDirPtr = NULL;
  961. LPSTR dirPtr = NULL;
  962. CHAR dirName[MAX_PATH];
  963. CHAR dirName2[MAX_PATH];
  964. LPSTR dirPtr2 = NULL;
  965. LPSTR dirLvlPtr = NULL;
  966. INT dirLvlCnt = 0;
  967. BOOL componentInit = FALSE;
  968. BOOL directoryInit = FALSE;
  969. Uuid* uuid;
  970. File* toBeRemoved;
  971. CHAR fileObjectName[MAX_PATH];
  972. UINT matchCount;
  973. //
  974. // Check destination directory.
  975. //
  976. if (item->isWindowsDir() != bWinDir)
  977. {
  978. item = item->getNext();
  979. continue;
  980. }
  981. //
  982. // Check is the destination is base dir
  983. //
  984. if (*(item->getDirectoryDestination()) == '\0')
  985. {
  986. //
  987. // Component
  988. //
  989. uuid = new Uuid();
  990. for (j = -1; j < dirLvlCnt+1; j++) {spaces[j+1] = ' '; spaces[j+2] = '\0';}
  991. sprintf( itemDescription, "%s<Component Id='%s'>Content%i", spaces, uuid->getString(), dwComponentCounter);
  992. delete uuid;
  993. PrintLine(hFile, itemDescription);
  994. //
  995. // File
  996. //
  997. for (j = -1; j < dirLvlCnt+2; j++) {spaces[j+1] = ' '; spaces[j+2] = '\0';}
  998. removeSpace(item->getName(), fileObjectName);
  999. sprintf( itemDescription,
  1000. "%s<File Name=\"%s\" LongName=\"%s\" Compressed='yes' src=\"%s\\%s\">%s.%i</File>",
  1001. spaces,
  1002. item->getName(),
  1003. item->getName(),
  1004. item->getSrcDir(),
  1005. item->getSrcName(),
  1006. fileObjectName,
  1007. dwComponentCounter);
  1008. PrintLine(hFile, itemDescription);
  1009. //
  1010. // </Component>
  1011. //
  1012. for (j = -1; j < dirLvlCnt+1; j++) {spaces[j+1] = ' '; spaces[j+2] = '\0';}
  1013. sprintf( itemDescription, "%s</Component>", spaces);
  1014. PrintLine(hFile, itemDescription);
  1015. dwComponentCounter++;
  1016. toBeRemoved = item;
  1017. item = item->getNext();
  1018. list->remove(toBeRemoved);
  1019. continue;
  1020. }
  1021. //
  1022. // Print directory
  1023. //
  1024. sprintf(dirName, "%s",item->getDirectoryDestination());
  1025. dirPtr = dirName;
  1026. refDirPtr = dirPtr;
  1027. while (dirPtr != NULL)
  1028. {
  1029. dirLvlPtr = strchr(dirPtr, '\\');
  1030. if (dirLvlPtr != NULL)
  1031. {
  1032. *dirLvlPtr = '\0';
  1033. for (j = -1; j < dirLvlCnt; j++) {spaces[j+1] = ' '; spaces[j+2] = '\0';}
  1034. sprintf( itemDescription, "%s<Directory Name=\"%s\">%s%i", spaces, dirPtr, dirPtr, dwDirectoryCounter);
  1035. dwDirectoryCounter++;
  1036. PrintLine(hFile, itemDescription);
  1037. dirPtr = dirLvlPtr + 1;
  1038. dirLvlCnt++;
  1039. //
  1040. // Print all file under this specific directory
  1041. //
  1042. sprintf( dirName2, "%s", item->getDirectoryDestination());
  1043. dirName2[dirLvlPtr-refDirPtr] = '\0';
  1044. File* sameLvlItem = NULL;
  1045. matchCount = 0;
  1046. while((sameLvlItem = list->search(item, dirName2)) != NULL)
  1047. {
  1048. /* //
  1049. // Directory
  1050. //
  1051. if (!directoryInit)
  1052. {
  1053. for (j = -1; j < dirLvlCnt; j++) {spaces[j+1] = ' '; spaces[j+2] = '\0';}
  1054. sprintf( itemDescription, "%s<Directory Name=\"%s\">%s%i", spaces, dirPtr, dirPtr, dwDirectoryCounter);
  1055. dwDirectoryCounter++;
  1056. PrintLine(hFile, itemDescription);
  1057. dirLvlCnt++;
  1058. directoryInit = TRUE;
  1059. }
  1060. */
  1061. //
  1062. // Component
  1063. //
  1064. if (!componentInit)
  1065. {
  1066. uuid = new Uuid();
  1067. for (j = -1; j < dirLvlCnt+1; j++) {spaces[j+1] = ' '; spaces[j+2] = '\0';}
  1068. sprintf( itemDescription, "%s<Component Id='%s'>Content%i", spaces, uuid->getString(), dwComponentCounter);
  1069. delete uuid;
  1070. PrintLine(hFile, itemDescription);
  1071. dwComponentCounter++;
  1072. componentInit = TRUE;
  1073. }
  1074. //
  1075. // File
  1076. //
  1077. matchCount++;
  1078. for (j = -1; j < dirLvlCnt+2; j++) {spaces[j+1] = ' '; spaces[j+2] = '\0';}
  1079. removeSpace(sameLvlItem->getName(), fileObjectName);
  1080. sprintf( itemDescription,
  1081. "%s<File Name=\"%s\" LongName=\"%s\" Compressed='yes' src=\"%s\\%s\">%s.%i</File>",
  1082. spaces,
  1083. sameLvlItem->getName(),
  1084. sameLvlItem->getName(),
  1085. sameLvlItem->getSrcDir(),
  1086. sameLvlItem->getSrcName(),
  1087. fileObjectName,
  1088. dwComponentCounter);
  1089. PrintLine(hFile, itemDescription);
  1090. list->remove(sameLvlItem);
  1091. }
  1092. if (matchCount)
  1093. {
  1094. //
  1095. // File
  1096. //
  1097. for (j = -1; j < dirLvlCnt+2; j++) {spaces[j+1] = ' '; spaces[j+2] = '\0';}
  1098. removeSpace(item->getName(), fileObjectName);
  1099. sprintf( itemDescription,
  1100. "%s<File Name=\"%s\" LongName=\"%s\" Compressed='yes' src=\"%s\\%s\">%s.%i</File>",
  1101. spaces,
  1102. item->getName(),
  1103. item->getName(),
  1104. item->getSrcDir(),
  1105. item->getSrcName(),
  1106. fileObjectName,
  1107. dwComponentCounter);
  1108. PrintLine(hFile, itemDescription);
  1109. dirPtr = NULL;
  1110. }
  1111. //
  1112. // Close component
  1113. //
  1114. if (componentInit)
  1115. {
  1116. for (j = -1; j < dirLvlCnt+1; j++) {spaces[j+1] = ' '; spaces[j+2] = '\0';}
  1117. sprintf( itemDescription, "%s</Component>", spaces);
  1118. PrintLine(hFile, itemDescription);
  1119. componentInit = FALSE;
  1120. }
  1121. //
  1122. // Close directory
  1123. //
  1124. if (directoryInit)
  1125. {
  1126. dirLvlCnt--;
  1127. for (j = -1; j < dirLvlCnt; j++) {spaces[j+1] = ' '; spaces[j+2] = '\0';}
  1128. sprintf( itemDescription, "%s</Directory>", spaces);
  1129. PrintLine(hFile, itemDescription);
  1130. directoryInit = FALSE;
  1131. }
  1132. }
  1133. else
  1134. {
  1135. if (!directoryInit)
  1136. {
  1137. for (j = -1; j < dirLvlCnt; j++) {spaces[j+1] = ' '; spaces[j+2] = '\0';}
  1138. sprintf( itemDescription, "%s<Directory Name=\"%s\">%s%i", spaces, dirPtr, dirPtr, dwDirectoryCounter);
  1139. dwDirectoryCounter++;
  1140. PrintLine(hFile, itemDescription);
  1141. dirLvlCnt++;
  1142. directoryInit = TRUE;
  1143. }
  1144. //
  1145. // Component
  1146. //
  1147. if (!componentInit)
  1148. {
  1149. uuid = new Uuid();
  1150. for (j = -1; j < dirLvlCnt+1; j++) {spaces[j+1] = ' '; spaces[j+2] = '\0';}
  1151. sprintf( itemDescription, "%s<Component Id='%s'>Content%i", spaces, uuid->getString(), dwComponentCounter);
  1152. delete uuid;
  1153. PrintLine(hFile, itemDescription);
  1154. componentInit = TRUE;
  1155. }
  1156. //
  1157. // Print all file under this specific directory
  1158. //
  1159. File* sameLvlItem;
  1160. while((sameLvlItem = list->search(item, item->getDirectoryDestination())) != NULL)
  1161. {
  1162. //
  1163. // File
  1164. //
  1165. for (j = -1; j < dirLvlCnt+2; j++) {spaces[j+1] = ' '; spaces[j+2] = '\0';}
  1166. removeSpace(sameLvlItem->getName(), fileObjectName);
  1167. sprintf( itemDescription,
  1168. "%s<File Name=\"%s\" LongName=\"%s\" Compressed='yes' src=\"%s\\%s\">%s.%i</File>",
  1169. spaces,
  1170. sameLvlItem->getName(),
  1171. sameLvlItem->getName(),
  1172. sameLvlItem->getSrcDir(),
  1173. sameLvlItem->getSrcName(),
  1174. fileObjectName,
  1175. dwComponentCounter);
  1176. PrintLine(hFile, itemDescription);
  1177. list->remove(sameLvlItem);
  1178. }
  1179. //
  1180. // File
  1181. //
  1182. for (j = -1; j < dirLvlCnt+2; j++) {spaces[j+1] = ' '; spaces[j+2] = '\0';}
  1183. removeSpace(item->getName(), fileObjectName);
  1184. sprintf( itemDescription,
  1185. "%s<File Name=\"%s\" LongName=\"%s\" Compressed='yes' src=\"%s\\%s\">%s.%i</File>",
  1186. spaces,
  1187. item->getName(),
  1188. item->getName(),
  1189. item->getSrcDir(),
  1190. item->getSrcName(),
  1191. fileObjectName,
  1192. dwComponentCounter);
  1193. PrintLine(hFile, itemDescription);
  1194. dwComponentCounter++;
  1195. dirPtr = NULL;
  1196. //
  1197. // Close component
  1198. //
  1199. if (componentInit)
  1200. {
  1201. for (j = -1; j < dirLvlCnt+1; j++) {spaces[j+1] = ' '; spaces[j+2] = '\0';}
  1202. sprintf( itemDescription, "%s</Component>", spaces);
  1203. PrintLine(hFile, itemDescription);
  1204. componentInit = FALSE;
  1205. }
  1206. //
  1207. // Close directory
  1208. //
  1209. if (directoryInit)
  1210. {
  1211. dirLvlCnt--;
  1212. for (j = -1; j < dirLvlCnt; j++) {spaces[j+1] = ' '; spaces[j+2] = '\0';}
  1213. sprintf( itemDescription, "%s</Directory>", spaces);
  1214. PrintLine(hFile, itemDescription);
  1215. directoryInit = FALSE;
  1216. }
  1217. }
  1218. }
  1219. for (int i = dirLvlCnt; i > 0; i--)
  1220. {
  1221. spaces[i] = '\0';
  1222. sprintf( itemDescription, "%s</Directory>", spaces);
  1223. PrintLine(hFile, itemDescription);
  1224. }
  1225. if (list->getFileNumber() > 1)
  1226. {
  1227. if (item->getNext() != NULL)
  1228. {
  1229. item = item->getNext();
  1230. list->remove(item->getPrevious());
  1231. }
  1232. else
  1233. {
  1234. list->remove(item);
  1235. item = NULL;
  1236. }
  1237. }
  1238. else
  1239. {
  1240. list->remove(item);
  1241. item = NULL;
  1242. }
  1243. }
  1244. }
  1245. else
  1246. {
  1247. File* item;
  1248. CHAR itemDescription[4096];
  1249. CHAR spaces[30];
  1250. int j;
  1251. item = list->getFirst();
  1252. while (item != NULL)
  1253. {
  1254. LPSTR dirPtr = NULL;
  1255. LPSTR dirLvlPtr = NULL;
  1256. INT dirLvlCnt = 0;
  1257. //
  1258. // Print directory
  1259. //
  1260. dirPtr = item->getDirectoryDestination();
  1261. while (dirPtr != NULL)
  1262. {
  1263. dirLvlPtr = strchr(dirPtr, '\\');
  1264. if (dirLvlPtr != NULL)
  1265. {
  1266. *dirLvlPtr = '\0';
  1267. for (j = -1; j < dirLvlCnt; j++) {spaces[j+1] = ' '; spaces[j+2] = '\0';}
  1268. sprintf( itemDescription, "%s<Directory Name=\"%s\">%s%i", spaces, dirPtr, dirPtr, dwDirectoryCounter);
  1269. dwDirectoryCounter++;
  1270. PrintLine(hFile, itemDescription);
  1271. dirPtr = dirLvlPtr + 1;
  1272. dirLvlCnt++;
  1273. }
  1274. else
  1275. {
  1276. Uuid* uuid = new Uuid();
  1277. for (j = -1; j < dirLvlCnt; j++) {spaces[j+1] = ' '; spaces[j+2] = '\0';}
  1278. sprintf( itemDescription, "%s<Directory Name=\"%s\">%s%i", spaces, dirPtr, dirPtr, dwDirectoryCounter);
  1279. dwDirectoryCounter++;
  1280. PrintLine(hFile, itemDescription);
  1281. dirLvlCnt++;
  1282. //
  1283. // Component
  1284. //
  1285. for (j = -1; j < dirLvlCnt+1; j++) {spaces[j+1] = ' '; spaces[j+2] = '\0';}
  1286. sprintf( itemDescription, "%s<Component Id='%s'>Content%i", spaces, uuid->getString(), dwComponentCounter);
  1287. delete uuid;
  1288. PrintLine(hFile, itemDescription);
  1289. //
  1290. // File
  1291. //
  1292. for (j = -1; j < dirLvlCnt+2; j++) {spaces[j+1] = ' '; spaces[j+2] = '\0';}
  1293. sprintf( itemDescription,
  1294. "%s<File Name=\"%s\" LongName=\"%s\" Compressed='yes' src=\"%s\\%s\">%s.%i</File>",
  1295. spaces,
  1296. item->getName(),
  1297. item->getName(),
  1298. item->getSrcDir(),
  1299. item->getSrcName(),
  1300. item->getName(),
  1301. dwComponentCounter);
  1302. PrintLine(hFile, itemDescription);
  1303. dwComponentCounter++;
  1304. dirPtr = NULL;
  1305. }
  1306. }
  1307. for (j = -1; j < dirLvlCnt+1; j++) {spaces[j+1] = ' '; spaces[j+2] = '\0';}
  1308. sprintf( itemDescription, "%s</Component>", spaces);
  1309. PrintLine(hFile, itemDescription);
  1310. for (int i = dirLvlCnt; i > 0; i--)
  1311. {
  1312. spaces[i] = '\0';
  1313. sprintf( itemDescription, "%s</Directory>", spaces);
  1314. PrintLine(hFile, itemDescription);
  1315. }
  1316. item = item->getNext();
  1317. }
  1318. }
  1319. /****************** DEBUG ******************
  1320. File* item;
  1321. CHAR itemDescription[4096];
  1322. item = list->getFirst();
  1323. while (item != NULL)
  1324. {
  1325. //
  1326. // Item description
  1327. //
  1328. sprintf(itemDescription,
  1329. " Source: %s\\%s",
  1330. item->getSrcDir(),
  1331. item->getSrcName());
  1332. PrintLine(hFile, itemDescription);
  1333. sprintf(itemDescription,
  1334. " Destination: %s\\%s",
  1335. item->getDirectoryDestination(),
  1336. item->getName());
  1337. PrintLine(hFile, itemDescription);
  1338. PrintLine(hFile, "");
  1339. item = item->getNext();
  1340. }
  1341. ****************** DEBUG ******************/
  1342. }
  1343. ////////////////////////////////////////////////////////////////////////////
  1344. //
  1345. // PrintLine
  1346. //
  1347. // Add a line at the end of the file.
  1348. //
  1349. ////////////////////////////////////////////////////////////////////////////
  1350. BOOL PrintLine(HANDLE hFile, LPCSTR lpLine)
  1351. {
  1352. DWORD dwBytesWritten;
  1353. SetFilePointer(hFile, 0, NULL, FILE_END);
  1354. WriteFile( hFile,
  1355. lpLine,
  1356. _tcslen(lpLine) * sizeof(TCHAR),
  1357. &dwBytesWritten,
  1358. NULL );
  1359. SetFilePointer(hFile, 0, NULL, FILE_END);
  1360. WriteFile( hFile,
  1361. TEXT("\r\n"),
  1362. _tcslen(TEXT("\r\n")) * sizeof(TCHAR),
  1363. &dwBytesWritten,
  1364. NULL );
  1365. return (TRUE);
  1366. }
  1367. ///////////////////////////////////////////////////////////////////////////////
  1368. //
  1369. // CreateOutputFile()
  1370. //
  1371. // Create the file that would received the package file contents.
  1372. //
  1373. ///////////////////////////////////////////////////////////////////////////////
  1374. HANDLE CreateOutputFile(LPSTR filename)
  1375. {
  1376. SECURITY_ATTRIBUTES SecurityAttributes;
  1377. //
  1378. // Sanity check.
  1379. //
  1380. if (filename == NULL)
  1381. {
  1382. return INVALID_HANDLE_VALUE;
  1383. }
  1384. //
  1385. // Create a security descriptor the output file.
  1386. //
  1387. SecurityAttributes.nLength = sizeof(SecurityAttributes);
  1388. SecurityAttributes.lpSecurityDescriptor = NULL;
  1389. SecurityAttributes.bInheritHandle = FALSE;
  1390. //
  1391. // Create the file.
  1392. //
  1393. return CreateFile( filename,
  1394. GENERIC_WRITE,
  1395. 0,
  1396. &SecurityAttributes,
  1397. OPEN_ALWAYS,
  1398. FILE_ATTRIBUTE_NORMAL,
  1399. NULL );
  1400. }
  1401. ////////////////////////////////////////////////////////////////////////////
  1402. //
  1403. // removeSpace
  1404. //
  1405. // Remove all space from a string.
  1406. //
  1407. ////////////////////////////////////////////////////////////////////////////
  1408. VOID removeSpace(LPSTR src, LPSTR dest)
  1409. {
  1410. LPSTR strSrcPtr = src;
  1411. LPSTR strDestPtr = dest;
  1412. while (*strSrcPtr != '\0')
  1413. {
  1414. if (*strSrcPtr != ' ')
  1415. {
  1416. *strDestPtr = *strSrcPtr;
  1417. strDestPtr++;
  1418. }
  1419. strSrcPtr++;
  1420. }
  1421. *strDestPtr = '\0';
  1422. }
  1423. ////////////////////////////////////////////////////////////////////////////
  1424. //
  1425. // TransNum
  1426. //
  1427. // Converts a number string to a dword value (in hex).
  1428. //
  1429. ////////////////////////////////////////////////////////////////////////////
  1430. DWORD TransNum(LPTSTR lpsz)
  1431. {
  1432. DWORD dw = 0L;
  1433. TCHAR c;
  1434. while (*lpsz)
  1435. {
  1436. c = *lpsz++;
  1437. if (c >= TEXT('A') && c <= TEXT('F'))
  1438. {
  1439. c -= TEXT('A') - 0xa;
  1440. }
  1441. else if (c >= TEXT('0') && c <= TEXT('9'))
  1442. {
  1443. c -= TEXT('0');
  1444. }
  1445. else if (c >= TEXT('a') && c <= TEXT('f'))
  1446. {
  1447. c -= TEXT('a') - 0xa;
  1448. }
  1449. else
  1450. {
  1451. break;
  1452. }
  1453. dw *= 0x10;
  1454. dw += c;
  1455. }
  1456. return (dw);
  1457. }
  1458. ///////////////////////////////////////////////////////////////////////////////
  1459. //
  1460. // Usage
  1461. //
  1462. // Print the fonction usage.
  1463. //
  1464. ///////////////////////////////////////////////////////////////////////////////
  1465. void Usage()
  1466. {
  1467. printf("Create filecontents_CORE.wxm, filecontents_PRO.wxm and filecontents_SRV.wxm\n");
  1468. printf("Usage: infparser /b:[32|64] /l:<lang> /f:[p|s|a|d] /s:<dir> /o:<file> /v\n");
  1469. printf(" where\n");
  1470. printf(" /b means the binary.\n");
  1471. printf(" 32: i386\n");
  1472. printf(" 64: ia64\n");
  1473. printf(" /l means the language flag.\n");
  1474. printf(" <lang>: is the target language\n");
  1475. printf(" /f means the flavor.\n");
  1476. printf(" p: Professional\n");
  1477. printf(" s: Server\n");
  1478. printf(" a: Advanced Server\n");
  1479. printf(" d: Data Center\n");
  1480. printf(" /s means the location of the binairy data.\n");
  1481. printf(" <dir>: Fully qualified path\n");
  1482. printf(" /o means the xml file contents of specific flavor.\n");
  1483. printf(" <file>: Fully qualified path\n");
  1484. printf(" /v means the verbose mode [optional].\n");
  1485. }