Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

660 lines
18 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. dosnet.c
  5. Abstract:
  6. This module implements a program that generates the [Files]
  7. section of dosnet.inf.
  8. The input consists of the layout inf; the output consists of
  9. an intermediary form of dosnet.inf.
  10. Author:
  11. Ted Miller (tedm) 20-May-1995
  12. Revision History:
  13. --*/
  14. #include <windows.h>
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <setupapi.h>
  18. #include <sputils.h>
  19. //
  20. // Define program result codes (returned from main()).
  21. //
  22. #define SUCCESS 0
  23. #define FAILURE 1
  24. //
  25. // Keep statistics...
  26. //
  27. INT ProcessedLines = 0;
  28. INT RemovedEntries = 0;
  29. INT DuplicateEntries = 0;
  30. INT PassThroughEntries = 0;
  31. HINF hExclusionInf = INVALID_HANDLE_VALUE;
  32. BOOL
  33. ParseArgs(
  34. IN int argc,
  35. IN char *argv[]
  36. )
  37. {
  38. return(argc > 5);
  39. }
  40. BOOL
  41. IsEntryInFilterFile(
  42. IN HINF hFilterinf,
  43. IN PCWSTR Inputval
  44. )
  45. {
  46. INFCONTEXT Context,SectionContext;
  47. PCWSTR CabName;
  48. WCHAR SectionName[LINE_LEN];
  49. UINT Field,
  50. FieldCount;
  51. //
  52. // First make sure we actually have a filter inf.
  53. // If not, then the entry certainly isn't in there.
  54. //
  55. if( !hFilterinf ) {
  56. return( FALSE );
  57. }
  58. //
  59. // Now get the section names that we have to search.
  60. //
  61. if (!SetupFindFirstLineW( hFilterinf, L"Version", L"CabFiles", &SectionContext)) {
  62. return( FALSE );
  63. }
  64. //
  65. // Search the sections for our entry.
  66. //
  67. do {
  68. FieldCount = SetupGetFieldCount(&SectionContext);
  69. for( Field=1; Field<=FieldCount; Field++ ) {
  70. if(SetupGetStringFieldW(&SectionContext,Field,SectionName,LINE_LEN,NULL)
  71. && SetupFindFirstLineW(hFilterinf, SectionName, Inputval, &Context)) {
  72. //
  73. // we found a match
  74. //
  75. return( TRUE );
  76. }
  77. }
  78. } while (SetupFindNextMatchLine(&SectionContext,TEXT("CabFiles"),&SectionContext));
  79. //
  80. // If we get here, we didn't find a match.
  81. //
  82. return( FALSE );
  83. }
  84. void
  85. AddToTempFile(
  86. PCWSTR FileName,
  87. PINFCONTEXT InfContext,
  88. FILE *TempFile
  89. ){
  90. WCHAR BootFloppyval[LINE_LEN];
  91. UCHAR line[MAX_INF_STRING_LENGTH];
  92. if(SetupGetStringFieldW(InfContext,7,BootFloppyval,LINE_LEN,NULL)
  93. && BootFloppyval[0]){
  94. WideCharToMultiByte(
  95. CP_OEMCP,
  96. 0,
  97. FileName,
  98. -1,
  99. line,
  100. sizeof(line),
  101. NULL,
  102. NULL
  103. );
  104. fprintf(TempFile,"%s\n",line);
  105. //fprintf(stderr,"xdosnet: Writing file %s\n",FileName);
  106. }
  107. return;
  108. }
  109. BOOL
  110. InExclusionList(
  111. PCWSTR FileName,
  112. PINFCONTEXT InfContext
  113. )
  114. {
  115. WCHAR BootFloppyval[LINE_LEN];
  116. INFCONTEXT Ctxt;
  117. //
  118. // first look in our global hardcoded exclusion list for the file
  119. //
  120. if (hExclusionInf != INVALID_HANDLE_VALUE) {
  121. if (SetupFindFirstLineW(hExclusionInf, L"Files", FileName, &Ctxt)) {
  122. // printf("excluding via inf file %ws\n",FileName);
  123. return(TRUE);
  124. }
  125. }
  126. //
  127. // now we need to see if this is a boot-disk file, which must be
  128. // excluded
  129. //
  130. if (SetupGetStringFieldW(InfContext,7,BootFloppyval,LINE_LEN,NULL)
  131. && !BootFloppyval[0]) {
  132. return(FALSE);
  133. }
  134. // printf("excluding boot file %ws\n",FileName);
  135. return(TRUE);
  136. }
  137. // Returns the DiskId of the file. This is basically
  138. // 1 or 2 for now.
  139. void pGetDiskIdStr(
  140. IN INFCONTEXT InputContext,
  141. IN DWORD DiskID,
  142. IN PSTR StrDiskID,
  143. IN DWORD StrLen
  144. )
  145. {
  146. WCHAR Tmp[20];
  147. if ( DiskID == -1 )
  148. {
  149. if(SetupGetStringFieldW(&InputContext,1,Tmp,sizeof(Tmp)/sizeof(WCHAR),NULL))
  150. {
  151. // Hack to make the CHS, CHT & KOR builds working. They use 7 as the
  152. // diskid for some reason. This means unless we do this hack the binaries
  153. // are marked to be on the 7th disk and that creates havoc with winnt.exe
  154. // not being able to copy stuff etc.
  155. // The hack is to see if the diskid is 7 and if it is then reset it to
  156. // 1. This is what would have happened before the 2CD changes to
  157. // xdosnet.exe, makefile.inc in MergedComponents\SetupInfs
  158. if ( ! lstrcmpW(Tmp,L"7") )
  159. lstrcpyW(Tmp, L"1");
  160. }
  161. else
  162. {
  163. // say it is d1 if the above fails
  164. lstrcpyW(Tmp,L"1");
  165. }
  166. }
  167. else
  168. {
  169. swprintf(Tmp, L"%d", DiskID);
  170. }
  171. WideCharToMultiByte(
  172. CP_OEMCP,
  173. 0,
  174. Tmp,
  175. -1,
  176. StrDiskID,
  177. StrLen,
  178. NULL,
  179. NULL
  180. );
  181. }
  182. BOOL
  183. DoSection(
  184. IN HINF hInputinf,
  185. IN PCWSTR InputSectionName,
  186. IN HINF hFilterinf,
  187. IN DWORD DiskID,
  188. IN FILE *OutFile,
  189. IN FILE *ExcludeFile,
  190. IN FILE *TempFile
  191. )
  192. {
  193. #define VERBOSE 1
  194. INFCONTEXT InputContext;
  195. UCHAR line[MAX_INF_STRING_LENGTH];
  196. WCHAR Inputval[MAX_INF_STRING_LENGTH];
  197. BOOL WriteEntry = TRUE;
  198. UCHAR StrDiskID[20];
  199. if(SetupFindFirstLineW(hInputinf,InputSectionName,NULL,&InputContext)) {
  200. do {
  201. //
  202. // Keep track of how many lines we process from the original inf (layout.inf)
  203. //
  204. ProcessedLines++;
  205. if(SetupGetStringFieldW(&InputContext,0,Inputval,MAX_INF_STRING_LENGTH,NULL)) {
  206. //
  207. // Assume the entry is good unless proven otherwise.
  208. //
  209. WriteEntry = TRUE;
  210. if( TempFile ) {
  211. AddToTempFile( Inputval, &InputContext, TempFile );
  212. }
  213. //
  214. // See if it's in the filter file.
  215. //
  216. if( IsEntryInFilterFile( hFilterinf, Inputval ) ) {
  217. if (!InExclusionList(Inputval, &InputContext )) {
  218. //
  219. // It's in the exclusion list. Skip it.
  220. //
  221. RemovedEntries++;
  222. WriteEntry = FALSE;
  223. if (ExcludeFile) {
  224. if( WideCharToMultiByte(
  225. CP_OEMCP,
  226. 0,
  227. Inputval,
  228. -1,
  229. line,
  230. sizeof(line),
  231. NULL,
  232. NULL
  233. ) ){
  234. fprintf(ExcludeFile,"%s\n",line);
  235. }
  236. }
  237. } else {
  238. //
  239. // It's a boot file. Keep it. Note that it's a
  240. // duplicate and will appear both inside and outside
  241. // the CAB.
  242. //
  243. DuplicateEntries++;
  244. }
  245. } else {
  246. //
  247. // It's not even in the filter file. Log it for
  248. // statistics.
  249. //
  250. PassThroughEntries++;
  251. }
  252. //
  253. // Write the entry out only if it's not supposed to
  254. // be filtered out.
  255. //
  256. if( WriteEntry ) {
  257. //
  258. // Dosnet.inf is in OEM chars.
  259. //
  260. WideCharToMultiByte(
  261. CP_OEMCP,
  262. 0,
  263. Inputval,
  264. -1,
  265. line,
  266. sizeof(line),
  267. NULL,
  268. NULL
  269. );
  270. // We need to find the disk this file is on and add that
  271. // to the file description.
  272. pGetDiskIdStr(InputContext, DiskID, StrDiskID, sizeof(StrDiskID));
  273. fprintf(OutFile,"d%s,%s\n",StrDiskID,line);
  274. }
  275. } else {
  276. fprintf(stderr,"A line in section %ws has no key\n",InputSectionName);
  277. return(FALSE);
  278. }
  279. } while(SetupFindNextLine(&InputContext,&InputContext));
  280. } else {
  281. fprintf(stderr,"Section %ws is empty or missing\n",InputSectionName);
  282. return(FALSE);
  283. }
  284. return(TRUE);
  285. }
  286. BOOL
  287. DoIt(
  288. IN char *InFilename,
  289. IN char *FilterFilename,
  290. IN DWORD DiskID,
  291. IN FILE *OutFile,
  292. IN FILE *ExcludeFile,
  293. IN char *PlatformExtension,
  294. IN FILE *TempFile
  295. )
  296. {
  297. PCWSTR inFilename;
  298. PCWSTR filterFilename;
  299. PCWSTR extension;
  300. HINF hInputinf,
  301. hFilterinf;
  302. BOOL b;
  303. WCHAR sectionName[256];
  304. INFCONTEXT Ctxt;
  305. b = FALSE;
  306. inFilename = pSetupAnsiToUnicode(InFilename);
  307. filterFilename = pSetupAnsiToUnicode(FilterFilename);
  308. //
  309. // Only proceed if we've got a file to work with.
  310. //
  311. if( inFilename ) {
  312. //
  313. // Only proceed if we've got a filter file to work with.
  314. //
  315. if( filterFilename ) {
  316. hInputinf = SetupOpenInfFileW(inFilename,NULL,INF_STYLE_WIN4,NULL);
  317. if(hInputinf != INVALID_HANDLE_VALUE) {
  318. //
  319. // If the filter-file fails, just keep going. This will
  320. // result in a big dosnet.inf, which means we'll have files
  321. // present both inside and outside the driver CAB, but
  322. // that's not fatal.
  323. //
  324. hFilterinf = SetupOpenInfFileW(filterFilename,NULL,INF_STYLE_WIN4,NULL);
  325. if(hFilterinf == INVALID_HANDLE_VALUE) {
  326. fprintf(stderr,"Unable to open inf file %s\n",FilterFilename);
  327. hFilterinf = NULL;
  328. }
  329. //
  330. // We're actually ready to process the sections!
  331. //
  332. fprintf(OutFile,"[Files]\n");
  333. if (ExcludeFile) {
  334. fprintf(ExcludeFile,"[Version]\n");
  335. fprintf(ExcludeFile,"signature=\"$Windows NT$\"\n");
  336. fprintf(ExcludeFile,"[Files]\n");
  337. }
  338. b = DoSection( hInputinf,
  339. L"SourceDisksFiles",
  340. hFilterinf,
  341. DiskID,
  342. OutFile,
  343. ExcludeFile,
  344. TempFile );
  345. if( b ) {
  346. //
  347. // Now process the x86-or-Alpha-specific section.
  348. //
  349. if(extension = pSetupAnsiToUnicode(PlatformExtension)) {
  350. lstrcpyW(sectionName,L"SourceDisksFiles");
  351. lstrcatW(sectionName,L".");
  352. lstrcatW(sectionName,extension);
  353. b = DoSection( hInputinf,
  354. sectionName,
  355. hFilterinf,
  356. DiskID,
  357. OutFile,
  358. ExcludeFile,
  359. TempFile );
  360. pSetupFree(extension);
  361. } else {
  362. fprintf(stderr,"Unable to convert string %s to Unicode\n",PlatformExtension);
  363. }
  364. }
  365. //Write the files in the input exclude INF to the [ForceCopyDriverCabFiles] section
  366. if (hExclusionInf != INVALID_HANDLE_VALUE) {
  367. WCHAR Filename[LINE_LEN];
  368. UCHAR line[MAX_INF_STRING_LENGTH];
  369. if (SetupFindFirstLineW(hExclusionInf, L"Files", NULL, &Ctxt)){
  370. fprintf(OutFile,"\n\n[ForceCopyDriverCabFiles]\n");
  371. do{
  372. if( SetupGetStringFieldW( &Ctxt, 1, Filename, LINE_LEN, NULL )){
  373. //
  374. // Dosnet.inf is in OEM chars.
  375. //
  376. WideCharToMultiByte(
  377. CP_OEMCP,
  378. 0,
  379. Filename,
  380. -1,
  381. line,
  382. sizeof(line),
  383. NULL,
  384. NULL
  385. );
  386. fprintf(OutFile,"%s\n",line);
  387. }
  388. }while( SetupFindNextLine( &Ctxt, &Ctxt ));
  389. }else{
  390. fprintf(stderr,"Could not find the Files section in the Exclude INF file\n");
  391. }
  392. }
  393. //
  394. // Print Statistics...
  395. //
  396. fprintf( stderr, " Total lines processed: %6d\n", ProcessedLines );
  397. fprintf( stderr, " Entries removed via filter file: %6d\n", RemovedEntries );
  398. fprintf( stderr, "Entries appearing both inside and outside driver CAB: %6d\n", DuplicateEntries );
  399. fprintf( stderr, " Entries not appearing in filter file: %6d\n", PassThroughEntries );
  400. //
  401. // Close up our inf handles.
  402. //
  403. if( hFilterinf ) {
  404. SetupCloseInfFile( hFilterinf );
  405. }
  406. SetupCloseInfFile(hInputinf);
  407. } else {
  408. fprintf(stderr,"Unable to open inf file %s\n",InFilename);
  409. }
  410. pSetupFree( filterFilename );
  411. } else {
  412. fprintf(stderr,"Unable to convert filename %s to Unicode\n",FilterFilename);
  413. }
  414. pSetupFree(inFilename);
  415. } else {
  416. fprintf(stderr,"Unable to convert filename %s to Unicode\n",InFilename);
  417. return(FALSE);
  418. }
  419. return(b);
  420. }
  421. int
  422. __cdecl
  423. main(
  424. IN int argc,
  425. IN char *argv[]
  426. )
  427. {
  428. FILE *OutputFile,*ExcludeFile, *TempFile;
  429. BOOL b;
  430. DWORD DiskID;
  431. char input_filename_fullpath[MAX_PATH];
  432. char *p;
  433. //
  434. // Assume failure.
  435. //
  436. b = FALSE;
  437. if(!pSetupInitializeUtils()) {
  438. return FAILURE;
  439. }
  440. if(ParseArgs(argc,argv)) {
  441. //
  442. // Open the output file.
  443. //
  444. OutputFile = fopen(argv[4],"wt");
  445. if (argc >= 7) {
  446. ExcludeFile = fopen(argv[6],"wt");
  447. } else {
  448. ExcludeFile = NULL;
  449. }
  450. if (argc >= 8) {
  451. hExclusionInf = SetupOpenInfFileA(argv[7],NULL,INF_STYLE_WIN4,NULL);
  452. if (hExclusionInf != INVALID_HANDLE_VALUE) {
  453. fprintf(stderr,"xdosnet: Opened file %s\n",argv[7]);
  454. }
  455. } else {
  456. hExclusionInf = INVALID_HANDLE_VALUE;
  457. }
  458. if (argc >= 9) {
  459. TempFile = fopen(argv[8],"wt");
  460. if( !TempFile )
  461. fprintf(stderr,"%s: Unable to create temp file %s\n",argv[0],argv[8]);
  462. //fprintf(stderr,"xdosnet: Created file %s\n",argv[8]);
  463. }else{
  464. TempFile = NULL;
  465. }
  466. // Special case handling Disk 1, Disk 2 etc. for x86. Since we want to process
  467. // all lines - this just means ignore the disk id specified on the command line
  468. // and pick up the Disk ID that is specified in the layout.inx entry itself.
  469. if ( argv[3][0] == '*' )
  470. DiskID = -1;
  471. else
  472. DiskID = atoi(argv[3]);
  473. GetFullPathName(
  474. argv[1],
  475. sizeof(input_filename_fullpath),
  476. input_filename_fullpath,
  477. &p);
  478. if(OutputFile) {
  479. fprintf(
  480. stdout,
  481. "%s: creating %s from %s and %s for %s (%s)\n",
  482. argv[0],
  483. argv[4],
  484. input_filename_fullpath,
  485. argv[2],
  486. argv[5],
  487. argv[6]);
  488. b = DoIt( input_filename_fullpath,
  489. argv[2],
  490. DiskID,
  491. OutputFile,
  492. ExcludeFile,
  493. argv[5],
  494. TempFile);
  495. fclose(OutputFile);
  496. } else {
  497. fprintf(stderr,"%s: Unable to create output file %s\n",argv[0],argv[3]);
  498. }
  499. if (ExcludeFile) {
  500. fclose(ExcludeFile);
  501. }
  502. if (TempFile) {
  503. fclose(TempFile);
  504. }
  505. } else {
  506. fprintf( stderr,"Merge 3 inf files. Usage:\n" );
  507. fprintf( stderr,"%s <input file1> <filter file> <diskid> <output file> <platform extension> <optional output exclude file> <optional input exclusion inf>\n", argv[0] );
  508. fprintf( stderr,"\n" );
  509. fprintf( stderr," <input file1> - original inf file (i.e. layout.inf)\n" );
  510. fprintf( stderr," <filter file> - contains a list of entries to be excluded\n" );
  511. fprintf( stderr," from the final output file\n" );
  512. fprintf( stderr," <disk id> - output disk id (i.e. 1 or 2)\n" );
  513. fprintf( stderr," <output file> - output inf (i.e. dosnet.inf)\n" );
  514. fprintf( stderr," <platform extension>\n" );
  515. fprintf( stderr," <output exclude file> - optional output file containing files that were filtered\n" );
  516. fprintf( stderr," <input exclusion inf> - optional input inf containing files that should never be filtered\n" );
  517. fprintf( stderr," <temp file> - optional file to be used to write boot file list into (IA64 temporary workaround)\n");
  518. fprintf( stderr,"\n" );
  519. fprintf( stderr,"\n" );
  520. }
  521. pSetupUninitializeUtils();
  522. return(b ? SUCCESS : FAILURE);
  523. }