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.

762 lines
23 KiB

  1. #include <tchar.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <windows.h>
  5. #include "utils.h"
  6. // config.ini file should look like this:
  7. // [sld_info]
  8. // Input_Ini_FileName=test.ini
  9. // Input_GUID={E66B49F6-4A35-4246-87E8-5C1A468315B5}
  10. // Input_BuildTypeMask=819
  11. // Input_Inf_FileName=iis.inf
  12. // Input_Inf_CopySections=iis_doc_install
  13. // Input_Inf_SubstitutionSection=inf_dirid_substitutions
  14. // Output_AnsiFileName=sldinfo.txt
  15. //
  16. //[inf_dirid_substitutions]
  17. //32768=%11%\inetsrv
  18. //
  19. /*
  20. <RESOURCE ResTypeVSGUID="{E66B49F6-4A35-4246-87E8-5C1A468315B5}" BuildTypeMask="819" Name="File(819):&quot;%18%\iisHelp\iis\htm\asp&quot;,&quot;IIS_aogu2wab.htm&quot;">
  21. <PROPERTY Name="SrcName" Format="String">IIS_aogu2wab.htm
  22. </PROPERTY>
  23. <PROPERTY Name="DstPath" Format="String">%18%\iisHelp\iis\htm\asp
  24. </PROPERTY>
  25. <PROPERTY Name="DstName" Format="String">IIS_aogu2wab.htm
  26. </PROPERTY>
  27. <PROPERTY Name="NoExpand" Format="Boolean">0
  28. </PROPERTY>
  29. </RESOURCE>
  30. */
  31. typedef struct _ProcessSLDinfo {
  32. TCHAR Input_Ini_FileName[_MAX_PATH];
  33. TCHAR Input_GUID[_MAX_PATH];
  34. TCHAR Input_BuildTypeMask[_MAX_PATH];
  35. TCHAR Input_Inf_FileName[_MAX_PATH];
  36. TCHAR Input_Inf_CopySections[_MAX_PATH + _MAX_PATH + _MAX_PATH + _MAX_PATH];
  37. TCHAR Input_Inf_SubstitutionSection[_MAX_PATH];
  38. TCHAR Output_AnsiFileName[_MAX_PATH];
  39. HINF hFileInf;
  40. HANDLE hFileOutput;
  41. } ProcessSLDinfo;
  42. #define INIFILE_SECTION _T("SLD_INFO")
  43. void ShowHelp(void);
  44. int ProcessParamFile(TCHAR *szFileName);
  45. int FillStructure(ProcessSLDinfo * MyInfo,TCHAR *szFileName);
  46. int ParseCommaDelimitedSectionDoSection(ProcessSLDinfo * MyInfo, LPTSTR szLine);
  47. int ProcessThisCopyFileSection(ProcessSLDinfo * MyInfo, LPTSTR szLine);
  48. int ParseCommaDelimitedSectionAndDoStuff(ProcessSLDinfo * MyInfo,LPTSTR szLine);
  49. int DoStuffWithThisSection(ProcessSLDinfo * MyInfo,LPTSTR szLine);
  50. int SearchThruKnownSectionForThisSection(ProcessSLDinfo * MyInfo, IN LPTSTR szSectionToMatch,OUT LPTSTR szReturnedDirInfo);
  51. int GimmieSubstituteNumber(ProcessSLDinfo * MyInfo, TCHAR * szOldNum, TCHAR * szReturnedString);
  52. int AppendToFile(HANDLE hFileOutput, TCHAR * szStringToAppend);
  53. //***************************************************************************
  54. //*
  55. //* purpose: main
  56. //*
  57. //***************************************************************************
  58. int __cdecl main(int argc,char *argv[])
  59. {
  60. int iRet = 0;
  61. int argno;
  62. char * pArg = NULL;
  63. char * pCmdStart = NULL;
  64. TCHAR szFilePath1[_MAX_PATH];
  65. TCHAR szFilePath2[_MAX_PATH];
  66. TCHAR szParamString_C[_MAX_PATH];
  67. int iDo_A = FALSE;
  68. int iDo_B = FALSE;
  69. int iDoVersion = FALSE;
  70. int iGotParamC = FALSE;
  71. *szFilePath1 = '\0';
  72. *szFilePath2 = '\0';
  73. *szParamString_C = '\0';
  74. _tcscpy(szFilePath1,_T(""));
  75. _tcscpy(szFilePath2,_T(""));
  76. _tcscpy(szParamString_C,_T(""));
  77. for(argno=1; argno<argc; argno++)
  78. {
  79. if ( argv[argno][0] == '-' || argv[argno][0] == '/' )
  80. {
  81. switch (argv[argno][1])
  82. {
  83. case 'a':
  84. case 'A':
  85. iDo_A = TRUE;
  86. break;
  87. case 'b':
  88. case 'B':
  89. iDo_B = TRUE;
  90. break;
  91. case 'v':
  92. case 'V':
  93. iDoVersion = TRUE;
  94. break;
  95. case 'c':
  96. case 'C':
  97. // Get the string for this flag
  98. pArg = CharNextA(argv[argno]);
  99. pArg = CharNextA(pArg);
  100. if (*pArg == ':')
  101. {
  102. char szTempString[_MAX_PATH];
  103. pArg = CharNextA(pArg);
  104. // Check if it's quoted
  105. if (*pArg == '\"')
  106. {
  107. pArg = CharNextA(pArg);
  108. pCmdStart = pArg;
  109. while ((*pArg) && (*pArg != '\"')){pArg = CharNextA(pArg);}
  110. }
  111. else
  112. {
  113. pCmdStart = pArg;
  114. while (*pArg){pArg = CharNextA(pArg);}
  115. }
  116. *pArg = '\0';
  117. lstrcpyA(szTempString, StripWhitespace(pCmdStart));
  118. // Convert to unicode
  119. #if defined(UNICODE) || defined(_UNICODE)
  120. MultiByteToWideChar(CP_ACP, 0, szTempString, -1, (LPWSTR) szParamString_C, _MAX_PATH);
  121. #else
  122. _tcscpy(szParamString_C,szTempString);
  123. #endif
  124. iGotParamC = TRUE;
  125. }
  126. break;
  127. case '?':
  128. goto main_exit_with_help;
  129. break;
  130. }
  131. }
  132. else
  133. {
  134. if (_tcsicmp(szFilePath1, _T("")) == 0)
  135. {
  136. // if no arguments, then get the filename portion
  137. #if defined(UNICODE) || defined(_UNICODE)
  138. MultiByteToWideChar(CP_ACP, 0, argv[argno], -1, (LPTSTR) szFilePath1, _MAX_PATH);
  139. #else
  140. _tcscpy(szFilePath1,argv[argno]);
  141. #endif
  142. }
  143. else
  144. {
  145. if (_tcsicmp(szFilePath2, _T("")) == 0)
  146. {
  147. // if no arguments, then get the filename portion
  148. #if defined(UNICODE) || defined(_UNICODE)
  149. MultiByteToWideChar(CP_ACP, 0, argv[argno], -1, (LPTSTR) szFilePath2, _MAX_PATH);
  150. #else
  151. _tcscpy(szFilePath2,argv[argno]);
  152. #endif
  153. }
  154. }
  155. }
  156. }
  157. //
  158. // Check what were supposed to do
  159. //
  160. if (TRUE == iDo_A || (FALSE == iDo_A && FALSE == iDo_B) )
  161. {
  162. // check for required parameters
  163. if (_tcsicmp(szFilePath1, _T("")) == 0)
  164. {
  165. _tprintf(_T("[-z] parameter missing filename1 parameter\n"));
  166. goto main_exit_with_help;
  167. }
  168. // call the function.
  169. iRet = ProcessParamFile(szFilePath1);
  170. if (FALSE == iRet)
  171. {
  172. iRet = 1;
  173. }
  174. else
  175. {
  176. iRet = 0;
  177. }
  178. }
  179. if (iDo_B)
  180. {
  181. // do stuff
  182. }
  183. if (TRUE == iDoVersion)
  184. {
  185. // output the version
  186. _tprintf(_T("1\n\n"));
  187. iRet = 10;
  188. goto main_exit_gracefully;
  189. }
  190. if (_tcsicmp(szFilePath1, _T("")) == 0)
  191. {
  192. goto main_exit_with_help;
  193. }
  194. goto main_exit_gracefully;
  195. main_exit_gracefully:
  196. exit(iRet);
  197. main_exit_with_help:
  198. ShowHelp();
  199. exit(iRet);
  200. }
  201. //***************************************************************************
  202. //*
  203. //* purpose: ?
  204. //*
  205. //***************************************************************************
  206. void ShowHelp(void)
  207. {
  208. TCHAR szModuleName[_MAX_PATH];
  209. TCHAR szFilename_only[_MAX_PATH];
  210. // get the modules full pathed filename
  211. if (0 != GetModuleFileName(NULL,(LPTSTR) szModuleName,_MAX_PATH))
  212. {
  213. // Trim off the filename only.
  214. _tsplitpath(szModuleName, NULL, NULL, szFilename_only, NULL);
  215. _tprintf(_T("Unicode File Utility\n\n"));
  216. _tprintf(_T("%s [-a] [-v] [-c:otherinfo] [drive:][path]filename1 [drive:][path]filename2\n\n"),szFilename_only);
  217. _tprintf(_T("[-a] paramter -- do stuff:\n"));
  218. _tprintf(_T(" -a required parameter for this functionality\n"));
  219. _tprintf(_T(" filename1 .ini file which controls what program should do\n"));
  220. _tprintf(_T("\n"));
  221. _tprintf(_T("Examples:\n"));
  222. _tprintf(_T("%s -a c:\\MyFileAnsi.ini\n"),szFilename_only);
  223. }
  224. return;
  225. }
  226. int FillStructure(ProcessSLDinfo * MyInfo, TCHAR *szFileName)
  227. {
  228. int iReturn = FALSE;
  229. TCHAR buf[_MAX_PATH];
  230. _tcscpy(buf,_T(""));
  231. if (IsFileExist(szFileName) != TRUE)
  232. {
  233. goto FillStructure_Exit;
  234. }
  235. // Input_GUID={E66B49F6-4A35-4246-87E8-5C1A468315B5}
  236. // Input_BuildTypeMask=819
  237. // Input_Inf_FileName=iis.inf
  238. // Input_Inf_CopySections=iis_doc_install
  239. // Input_Inf_SubstitutionSection=inf_dirid_substitutions
  240. // Output_AnsiFileName=sldinfo.txt
  241. _tcscpy(MyInfo->Input_Ini_FileName,szFileName);
  242. GetPrivateProfileString(INIFILE_SECTION, _T("Input_GUID"), _T(""), buf, _MAX_PATH, szFileName);
  243. if (NULL == *buf)
  244. {
  245. _tprintf(_T("Entry missing:Input_GUID\n"),buf);
  246. goto FillStructure_Exit;
  247. }
  248. _tcscpy(MyInfo->Input_GUID,buf);
  249. GetPrivateProfileString(INIFILE_SECTION, _T("Input_BuildTypeMask"), _T(""), buf, _MAX_PATH, szFileName);
  250. if (NULL == *buf)
  251. {
  252. _tprintf(_T("Entry missing:Input_BuildTypeMask\n"),buf);
  253. goto FillStructure_Exit;
  254. }
  255. _tcscpy(MyInfo->Input_BuildTypeMask,buf);
  256. GetPrivateProfileString(INIFILE_SECTION, _T("Input_Inf_FileName"), _T(""), buf, _MAX_PATH, szFileName);
  257. if (NULL == *buf)
  258. {
  259. _tprintf(_T("Entry missing:Input_Inf_FileName\n"),buf);
  260. goto FillStructure_Exit;
  261. }
  262. else
  263. {
  264. DoExpandEnvironmentStrings(buf);
  265. }
  266. _tcscpy(MyInfo->Input_Inf_FileName,buf);
  267. GetPrivateProfileString(INIFILE_SECTION, _T("Input_Inf_CopySections"), _T(""), buf, _MAX_PATH, szFileName);
  268. if (NULL == *buf)
  269. {
  270. _tprintf(_T("Entry missing:Input_Inf_CopySections\n"),buf);
  271. goto FillStructure_Exit;
  272. }
  273. _tcscpy(MyInfo->Input_Inf_CopySections,buf);
  274. GetPrivateProfileString(INIFILE_SECTION, _T("Input_Inf_SubstitutionSection"), _T(""), buf, _MAX_PATH, szFileName);
  275. if (NULL == *buf)
  276. {
  277. _tprintf(_T("Entry missing:Input_Inf_SubstitutionSection\n"),buf);
  278. goto FillStructure_Exit;
  279. }
  280. _tcscpy(MyInfo->Input_Inf_SubstitutionSection,buf);
  281. GetPrivateProfileString(INIFILE_SECTION, _T("Output_AnsiFileName"), _T(""), buf, _MAX_PATH, szFileName);
  282. if (NULL == *buf)
  283. {
  284. _tprintf(_T("Entry missing:Output_AnsiFileName\n"),buf);
  285. goto FillStructure_Exit;
  286. }
  287. _tcscpy(MyInfo->Output_AnsiFileName,buf);
  288. iReturn = TRUE;
  289. FillStructure_Exit:
  290. return iReturn;
  291. }
  292. int ProcessParamFile(TCHAR *szFileName)
  293. {
  294. int iReturn = FALSE;
  295. ProcessSLDinfo MyInfo;
  296. LPTSTR pch = NULL;
  297. _tprintf(_T("ProcessParamFile:Start\n"));
  298. // Check if there is a "\" in there.(since GetPrivateProfileString needs a fully qualified path)
  299. pch = _tcschr(szFileName, _T('\\'));
  300. if (!pch || IsFileExist(szFileName) != TRUE)
  301. {
  302. TCHAR szCurrentDir[_MAX_PATH];
  303. GetCurrentDirectory( _MAX_PATH, szCurrentDir);
  304. SetCurrentDirectory(szCurrentDir);
  305. AddPath(szCurrentDir,szFileName);
  306. _tcscpy(szFileName,szCurrentDir);
  307. if (IsFileExist(szFileName) != TRUE)
  308. {
  309. _tprintf(_T("File %s, not found\n"),szFileName);
  310. goto ProcessParamFile_Exit;
  311. }
  312. }
  313. // open the ini file
  314. // and set all the parameters
  315. iReturn = FillStructure(&MyInfo,szFileName);
  316. if (FALSE == iReturn)
  317. {
  318. _tprintf(_T("Missing required parameters from %s file\n"),szFileName);
  319. goto ProcessParamFile_Exit;
  320. }
  321. // check if the inf filename exists....
  322. if (IsFileExist(MyInfo.Input_Inf_FileName) != TRUE)
  323. {
  324. _tprintf(_T("File %s, not found\n"),MyInfo.Input_Inf_FileName);
  325. goto ProcessParamFile_Exit;
  326. }
  327. _tprintf(_T("ProcessParamFile:ini=%s\n"),MyInfo.Input_Ini_FileName);
  328. _tprintf(_T("ProcessParamFile:inf=%s\n"),MyInfo.Input_Inf_FileName);
  329. _tprintf(_T("ProcessParamFile:output=%s\n"),MyInfo.Output_AnsiFileName);
  330. // Open the .inf file
  331. // and look for the specified section
  332. // Get a handle to it.
  333. MyInfo.hFileInf = SetupOpenInfFile(MyInfo.Input_Inf_FileName, NULL, INF_STYLE_WIN4, NULL);
  334. if(MyInfo.hFileInf == INVALID_HANDLE_VALUE)
  335. {
  336. _tprintf(_T("err opening file %s\n"),MyInfo.Input_Inf_FileName);
  337. goto ProcessParamFile_Exit;
  338. }
  339. //
  340. // okay now do the work for ONE copyfile section
  341. //
  342. // open the output file
  343. // Create a new unicode file
  344. MyInfo.hFileOutput = INVALID_HANDLE_VALUE;
  345. MyInfo.hFileOutput = CreateFile((LPCTSTR) MyInfo.Output_AnsiFileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  346. if( MyInfo.hFileOutput == INVALID_HANDLE_VALUE)
  347. {
  348. _tprintf(_T("Failure to create file %s\n"),MyInfo.Output_AnsiFileName);
  349. goto ProcessParamFile_Exit;
  350. }
  351. // open list of copyfiles sections to get list of sections that we need to do....
  352. ParseCommaDelimitedSectionDoSection(&MyInfo,MyInfo.Input_Inf_CopySections);
  353. iReturn = TRUE;
  354. ProcessParamFile_Exit:
  355. if (INVALID_HANDLE_VALUE != MyInfo.hFileOutput)
  356. {CloseHandle(MyInfo.hFileOutput);MyInfo.hFileOutput = INVALID_HANDLE_VALUE;}
  357. if (INVALID_HANDLE_VALUE != MyInfo.hFileInf)
  358. {SetupCloseInfFile(MyInfo.hFileInf);MyInfo.hFileInf = INVALID_HANDLE_VALUE;}
  359. if (TRUE == iReturn)
  360. {
  361. _tprintf(_T("ProcessParamFile:Success! File=%s\n"),MyInfo.Output_AnsiFileName);
  362. }
  363. else
  364. {
  365. _tprintf(_T("ProcessParamFile:End FAILED\n"));
  366. }
  367. return iReturn;
  368. }
  369. // input is something like this:
  370. // iisdoc_files_common_default,iisdoc_files_common_htmldocs,iisdoc_files_common_admsampdocs,etc...
  371. // so we need to strtok thru this and act on every section that we process...
  372. //
  373. int ParseCommaDelimitedSectionDoSection(ProcessSLDinfo * MyInfo, LPTSTR szLine)
  374. {
  375. int iReturn = FALSE;
  376. TCHAR *token = NULL;
  377. token = _tcstok(szLine, _T(","));
  378. while (token != NULL)
  379. {
  380. ProcessThisCopyFileSection(MyInfo,token);
  381. token = _tcstok(NULL, _T(","));
  382. }
  383. return iReturn;
  384. }
  385. int ProcessThisCopyFileSection(ProcessSLDinfo * MyInfo, LPTSTR szTheSection)
  386. {
  387. int iReturn = FALSE;
  388. BOOL bFlag = FALSE;
  389. INFCONTEXT Context;
  390. DWORD dwRequiredSize = 0;
  391. LPTSTR szLine = NULL;
  392. if (FALSE == DoesThisSectionExist(MyInfo->hFileInf,szTheSection))
  393. {
  394. _tprintf(_T("section %s, doesn't exist in %s\n"),szTheSection,MyInfo->Input_Inf_FileName);
  395. goto ProcessThisCopyFileSection_Exit;
  396. }
  397. // go to the beginning of the section in the INF file
  398. bFlag = SetupFindFirstLine(MyInfo->hFileInf,szTheSection, NULL, &Context);
  399. if (!bFlag)
  400. {
  401. goto ProcessThisCopyFileSection_Exit;
  402. }
  403. // loop through the items in the section.
  404. while (bFlag)
  405. {
  406. // get the size of the memory we need for this
  407. bFlag = SetupGetLineText(&Context, NULL, NULL, NULL, NULL, 0, &dwRequiredSize);
  408. // prepare the buffer to receive the line
  409. szLine = (LPTSTR)GlobalAlloc( GPTR, dwRequiredSize * sizeof(TCHAR) );
  410. if ( !szLine )
  411. {
  412. _tprintf(_T("Failure to get memory\n"));
  413. goto ProcessThisCopyFileSection_Exit;
  414. }
  415. // get the line from the inf file1
  416. if (SetupGetLineText(&Context, NULL, NULL, NULL, szLine, dwRequiredSize, NULL) == FALSE)
  417. {
  418. _tprintf(_T("SetupGetLineText Failed\n"));
  419. goto ProcessThisCopyFileSection_Exit;
  420. }
  421. //print it out.
  422. // should come back as:
  423. // one big line...
  424. //iisdoc_files_common_default,iisdoc_files_common_htmldocs,iisdoc_files_common_admsampdocs,etc...
  425. // For each of these entries
  426. // do something
  427. ParseCommaDelimitedSectionAndDoStuff(MyInfo,szLine);
  428. // find the next line in the section. If there is no next line it should return false
  429. bFlag = SetupFindNextLine(&Context, &Context);
  430. // free the temporary buffer
  431. if (szLine) {GlobalFree(szLine);}
  432. szLine = NULL;
  433. iReturn = TRUE;
  434. }
  435. ProcessThisCopyFileSection_Exit:
  436. if (szLine) {GlobalFree(szLine);szLine=NULL;}
  437. return iReturn;
  438. }
  439. // input is something like this:
  440. // iisdoc_files_common_default,iisdoc_files_common_htmldocs,iisdoc_files_common_admsampdocs,etc...
  441. // so we need to strtok thru this and act on every section that we process...
  442. //
  443. int ParseCommaDelimitedSectionAndDoStuff(ProcessSLDinfo * MyInfo, LPTSTR szLine)
  444. {
  445. int iReturn = FALSE;
  446. TCHAR *token = NULL;
  447. token = _tcstok(szLine, _T(","));
  448. while (token != NULL)
  449. {
  450. DoStuffWithThisSection(MyInfo,token);
  451. token = _tcstok(NULL, _T(","));
  452. }
  453. return iReturn;
  454. }
  455. int SearchThruKnownSectionForThisSection(ProcessSLDinfo * MyInfo, IN LPTSTR szSectionToMatch,OUT LPTSTR szReturnedDirInfo)
  456. {
  457. int iReturn = FALSE;
  458. INFCONTEXT Context;
  459. BOOL bFlag = FALSE;
  460. DWORD dwRequiredSize = 0;
  461. TCHAR szTempString1[_MAX_PATH] = _T("");
  462. TCHAR szTempString2[_MAX_PATH] = _T("");
  463. DWORD dwTemp = 0;
  464. //[DestinationDirs]
  465. //iisdoc_files_common = 18, iisHelp\common
  466. //iisdoc_files_fonts = 20
  467. //iisdoc_files_common_default = 18, iisHelp
  468. // go to the beginning of the section in the INF file
  469. bFlag = SetupFindFirstLine(MyInfo->hFileInf,_T("DestinationDirs"), szSectionToMatch, &Context);
  470. if (!bFlag)
  471. {
  472. goto SearchThruKnownSectionForThisSection_Exit;
  473. }
  474. if (!SetupGetStringField(&Context, 1, szTempString1, _MAX_PATH, NULL))
  475. {
  476. goto SearchThruKnownSectionForThisSection_Exit;
  477. }
  478. // This string will come back something like
  479. //-01,0xffff The directory from which the INF was installed.
  480. //01 SourceDrive:\path.
  481. //10 Windows directory.
  482. //11 System directory. (%windir%\system on Windows 95, %windir%\system32 on Windows NT)
  483. //12 Drivers directory.(%windir%\system32\drivers on Windows NT)
  484. //17 INF file directory.
  485. //18 Help directory.
  486. //20 Fonts directory.
  487. //21 Viewers directory.
  488. //24 Applications directory.
  489. //25 Shared directory.
  490. //30 Root directory of the boot drive.
  491. //50 %windir%\system
  492. //51 Spool directory.
  493. //52 Spool drivers directory.
  494. //53 User Profile directory.
  495. //54 Path to ntldr or OSLOADER.EXE
  496. // if it's larger than 100 we probably don't know what it is
  497. // and it's probably been user defined
  498. _tcscpy(szReturnedDirInfo,szTempString1);
  499. dwTemp = _ttoi((LPCTSTR) szReturnedDirInfo);
  500. if (dwTemp >= 100)
  501. {
  502. if (FALSE == GimmieSubstituteNumber(MyInfo,szTempString1,szReturnedDirInfo))
  503. {
  504. // Failed to lookup number!
  505. _tprintf(_T("Failed find substitute for [%s] in section [%s] in file %s\n"),szTempString1,MyInfo->Input_Inf_SubstitutionSection,MyInfo->Input_Inf_FileName);
  506. }
  507. }
  508. else
  509. {
  510. _tcscpy(szReturnedDirInfo,_T("%"));
  511. _tcscat(szReturnedDirInfo,szTempString1);
  512. _tcscat(szReturnedDirInfo,_T("%"));
  513. }
  514. if (TRUE == SetupGetStringField(&Context, 2, szTempString2, _MAX_PATH, NULL))
  515. {
  516. _tcscat(szReturnedDirInfo,_T("\\"));
  517. _tcscat(szReturnedDirInfo,szTempString2);
  518. }
  519. iReturn = TRUE;
  520. SearchThruKnownSectionForThisSection_Exit:
  521. return iReturn;
  522. }
  523. int GimmieSubstituteNumber(ProcessSLDinfo * MyInfo, TCHAR * szOldNum, TCHAR * szReturnedString)
  524. {
  525. int iReturn = FALSE;
  526. BOOL bFlag = FALSE;
  527. INFCONTEXT Context;
  528. TCHAR szTempString[_MAX_PATH] = _T("");
  529. TCHAR szSectionToMatch[_MAX_PATH];
  530. HINF hFileInfTemporary;
  531. _tcscpy(szTempString,_T(""));
  532. _tcscpy(szReturnedString, _T("%"));
  533. _tcscat(szReturnedString, szOldNum);
  534. _tcscat(szReturnedString, _T("%"));
  535. GetPrivateProfileString(MyInfo->Input_Inf_SubstitutionSection, szOldNum, _T(""), szTempString, _MAX_PATH, MyInfo->Input_Ini_FileName);
  536. if (NULL == *szTempString)
  537. {
  538. iReturn = FALSE;
  539. goto GimmieSubstituteNumber_Exit;
  540. }
  541. else
  542. {
  543. _tcscpy(szReturnedString, szTempString);
  544. }
  545. iReturn = TRUE;
  546. GimmieSubstituteNumber_Exit:
  547. return iReturn;
  548. }
  549. int DoStuffWithThisSection(ProcessSLDinfo * MyInfo, LPTSTR szInputLine)
  550. {
  551. int iReturn = FALSE;
  552. BOOL bFlag = FALSE;
  553. TCHAR szReturnedDirInfo[_MAX_PATH];
  554. TCHAR szBigString[1000];
  555. TCHAR szFileName1[_MAX_PATH];
  556. DWORD dwRequiredSize = 0;
  557. INFCONTEXT Context;
  558. LPTSTR szLine = NULL;
  559. TCHAR szFileName[_MAX_PATH] = _T("");
  560. TCHAR szFileNameRename[_MAX_PATH] = _T("");
  561. if (FALSE == SearchThruKnownSectionForThisSection(MyInfo,szInputLine,szReturnedDirInfo))
  562. {
  563. goto DoStuffWithThisSection_Exit;
  564. }
  565. // Get the filename
  566. // go to the beginning of the section in the INF file
  567. bFlag = SetupFindFirstLine(MyInfo->hFileInf,szInputLine, NULL, &Context);
  568. if (!bFlag)
  569. {
  570. _tprintf(_T("Failed to find section for [%s] in %s\n"),szInputLine,MyInfo->Input_Inf_FileName);
  571. goto DoStuffWithThisSection_Exit;
  572. }
  573. while (bFlag)
  574. {
  575. if (!SetupGetStringField(&Context, 1, szFileName, _MAX_PATH, NULL))
  576. {
  577. break;
  578. }
  579. // see if there is a rename to field.
  580. _tcscpy(szFileNameRename, _T(""));
  581. _tcscpy(szFileNameRename, szFileName);
  582. SetupGetStringField(&Context, 2, szFileNameRename, _MAX_PATH, NULL);
  583. // Output this stuff an ansi file.
  584. /*
  585. <RESOURCE ResTypeVSGUID="{E66B49F6-4A35-4246-87E8-5C1A468315B5}" BuildTypeMask="819" Name="File(819):&quot;%18%\iisHelp\iis\htm\adminsamples&quot;,&quot;contftp.htm&quot;">
  586. <PROPERTY Name="SrcName" Format="String">IIS_contftp.htm</PROPERTY>
  587. <PROPERTY Name="DstPath" Format="String">%18%\iisHelp\iis\htm\adminsamples</PROPERTY>
  588. <PROPERTY Name="DstName" Format="String">contftp.htm</PROPERTY>
  589. <PROPERTY Name="NoExpand" Format="Boolean">0</PROPERTY>
  590. </RESOURCE>
  591. */
  592. // --------------------
  593. // Do RESOURCE END
  594. // --------------------
  595. _stprintf(szBigString, _T("<RESOURCE ResTypeVSGUID=\"%s\" BuildTypeMask=\"%s\" Name=\"File(%s):&quot;%s&quot;,&quot;%s&quot;\">"),
  596. MyInfo->Input_GUID,
  597. MyInfo->Input_BuildTypeMask,
  598. MyInfo->Input_BuildTypeMask,
  599. szReturnedDirInfo,
  600. szFileName);
  601. AppendToFile(MyInfo->hFileOutput, szBigString);
  602. // --------------------
  603. // Do SRCNAME PROPERTY
  604. // --------------------
  605. _stprintf(szBigString, _T("<PROPERTY Name=\"SrcName\" Format=\"String\">%s</PROPERTY>"),szFileNameRename);
  606. AppendToFile(MyInfo->hFileOutput, szBigString);
  607. // --------------------
  608. // Do DSTPATH PROPERTY
  609. // --------------------
  610. _stprintf(szBigString, _T("<PROPERTY Name=\"DstPath\" Format=\"String\">%s</PROPERTY>"),szReturnedDirInfo);
  611. AppendToFile(MyInfo->hFileOutput, szBigString);
  612. // --------------------
  613. // Do DSTNAME PROPERTY
  614. // --------------------
  615. _stprintf(szBigString, _T("<PROPERTY Name=\"DstName\" Format=\"String\">%s</PROPERTY>"),szFileName);
  616. AppendToFile(MyInfo->hFileOutput, szBigString);
  617. // --------------------
  618. // Do NOEXPAND PROPERTY
  619. // --------------------
  620. _stprintf(szBigString, _T("<PROPERTY Name=\"NoExpand\" Format=\"Boolean\">0</PROPERTY>"));
  621. AppendToFile(MyInfo->hFileOutput, szBigString);
  622. // --------------------
  623. // Do RESOURCE END
  624. // --------------------
  625. _stprintf(szBigString, _T("</RESOURCE>"));
  626. AppendToFile(MyInfo->hFileOutput, szBigString);
  627. // find the next line in the section. If there is no next line it should return false
  628. bFlag = SetupFindNextLine(&Context, &Context);
  629. }
  630. iReturn = TRUE;
  631. DoStuffWithThisSection_Exit:
  632. return iReturn;
  633. }
  634. int AppendToFile(HANDLE hFileOutput, TCHAR * szStringToAppend)
  635. {
  636. int iReturn = FALSE;
  637. DWORD dwBytesWritten = 0;
  638. if (hFileOutput)
  639. {
  640. if (WriteFile(hFileOutput,szStringToAppend,_tcslen(szStringToAppend),&dwBytesWritten,NULL))
  641. {
  642. iReturn = TRUE;
  643. }
  644. else
  645. {
  646. _tprintf(_T("WriteFile FAILED:err=0x%x\n"),GetLastError());
  647. }
  648. }
  649. return iReturn;
  650. }