/*++ Copyright (c) 1995 Microsoft Corporation Module Name: dosnet.c Abstract: This module implements a program that generates the [Files] section of dosnet.inf. The input consists of the layout inf; the output consists of an intermediary form of dosnet.inf. Author: Ted Miller (tedm) 20-May-1995 Revision History: --*/ #include #include #include #include #include // // Define program result codes (returned from main()). // #define SUCCESS 0 #define FAILURE 1 // // Keep statistics... // INT ProcessedLines = 0; INT RemovedEntries = 0; INT DuplicateEntries = 0; INT PassThroughEntries = 0; HINF hExclusionInf = INVALID_HANDLE_VALUE; BOOL ParseArgs( IN int argc, IN char *argv[] ) { return(argc > 5); } BOOL IsEntryInFilterFile( IN HINF hFilterinf, IN PCWSTR Inputval ) { INFCONTEXT Context,SectionContext; PCWSTR CabName; WCHAR SectionName[LINE_LEN]; UINT Field, FieldCount; // // First make sure we actually have a filter inf. // If not, then the entry certainly isn't in there. // if( !hFilterinf ) { return( FALSE ); } // // Now get the section names that we have to search. // if (!SetupFindFirstLineW( hFilterinf, L"Version", L"CabFiles", &SectionContext)) { return( FALSE ); } // // Search the sections for our entry. // do { FieldCount = SetupGetFieldCount(&SectionContext); for( Field=1; Field<=FieldCount; Field++ ) { if(SetupGetStringFieldW(&SectionContext,Field,SectionName,LINE_LEN,NULL) && SetupFindFirstLineW(hFilterinf, SectionName, Inputval, &Context)) { // // we found a match // return( TRUE ); } } } while (SetupFindNextMatchLine(&SectionContext,TEXT("CabFiles"),&SectionContext)); // // If we get here, we didn't find a match. // return( FALSE ); } void AddToTempFile( PCWSTR FileName, PINFCONTEXT InfContext, FILE *TempFile ){ WCHAR BootFloppyval[LINE_LEN]; UCHAR line[MAX_INF_STRING_LENGTH]; if(SetupGetStringFieldW(InfContext,7,BootFloppyval,LINE_LEN,NULL) && BootFloppyval[0]){ WideCharToMultiByte( CP_OEMCP, 0, FileName, -1, line, sizeof(line), NULL, NULL ); fprintf(TempFile,"%s\n",line); //fprintf(stderr,"xdosnet: Writing file %s\n",FileName); } return; } BOOL InExclusionList( PCWSTR FileName, PINFCONTEXT InfContext ) { WCHAR BootFloppyval[LINE_LEN]; INFCONTEXT Ctxt; // // first look in our global hardcoded exclusion list for the file // if (hExclusionInf != INVALID_HANDLE_VALUE) { if (SetupFindFirstLineW(hExclusionInf, L"Files", FileName, &Ctxt)) { // printf("excluding via inf file %ws\n",FileName); return(TRUE); } } // // now we need to see if this is a boot-disk file, which must be // excluded // if (SetupGetStringFieldW(InfContext,7,BootFloppyval,LINE_LEN,NULL) && !BootFloppyval[0]) { return(FALSE); } // printf("excluding boot file %ws\n",FileName); return(TRUE); } // Returns the DiskId of the file. This is basically // 1 or 2 for now. void pGetDiskIdStr( IN INFCONTEXT InputContext, IN DWORD DiskID, IN PSTR StrDiskID, IN DWORD StrLen ) { WCHAR Tmp[20]; if ( DiskID == -1 ) { if(SetupGetStringFieldW(&InputContext,1,Tmp,sizeof(Tmp)/sizeof(WCHAR),NULL)) { // Hack to make the CHS, CHT & KOR builds working. They use 7 as the // diskid for some reason. This means unless we do this hack the binaries // are marked to be on the 7th disk and that creates havoc with winnt.exe // not being able to copy stuff etc. // The hack is to see if the diskid is 7 and if it is then reset it to // 1. This is what would have happened before the 2CD changes to // xdosnet.exe, makefile.inc in MergedComponents\SetupInfs if ( ! lstrcmpW(Tmp,L"7") ) lstrcpyW(Tmp, L"1"); } else { // say it is d1 if the above fails lstrcpyW(Tmp,L"1"); } } else { swprintf(Tmp, L"%d", DiskID); } WideCharToMultiByte( CP_OEMCP, 0, Tmp, -1, StrDiskID, StrLen, NULL, NULL ); } BOOL DoSection( IN HINF hInputinf, IN PCWSTR InputSectionName, IN HINF hFilterinf, IN DWORD DiskID, IN FILE *OutFile, IN FILE *ExcludeFile, IN FILE *TempFile ) { #define VERBOSE 1 INFCONTEXT InputContext; UCHAR line[MAX_INF_STRING_LENGTH]; WCHAR Inputval[MAX_INF_STRING_LENGTH]; BOOL WriteEntry = TRUE; UCHAR StrDiskID[20]; if(SetupFindFirstLineW(hInputinf,InputSectionName,NULL,&InputContext)) { do { // // Keep track of how many lines we process from the original inf (layout.inf) // ProcessedLines++; if(SetupGetStringFieldW(&InputContext,0,Inputval,MAX_INF_STRING_LENGTH,NULL)) { // // Assume the entry is good unless proven otherwise. // WriteEntry = TRUE; if( TempFile ) { AddToTempFile( Inputval, &InputContext, TempFile ); } // // See if it's in the filter file. // if( IsEntryInFilterFile( hFilterinf, Inputval ) ) { if (!InExclusionList(Inputval, &InputContext )) { // // It's in the exclusion list. Skip it. // RemovedEntries++; WriteEntry = FALSE; if (ExcludeFile) { if( WideCharToMultiByte( CP_OEMCP, 0, Inputval, -1, line, sizeof(line), NULL, NULL ) ){ fprintf(ExcludeFile,"%s\n",line); } } } else { // // It's a boot file. Keep it. Note that it's a // duplicate and will appear both inside and outside // the CAB. // DuplicateEntries++; } } else { // // It's not even in the filter file. Log it for // statistics. // PassThroughEntries++; } // // Write the entry out only if it's not supposed to // be filtered out. // if( WriteEntry ) { // // Dosnet.inf is in OEM chars. // WideCharToMultiByte( CP_OEMCP, 0, Inputval, -1, line, sizeof(line), NULL, NULL ); // We need to find the disk this file is on and add that // to the file description. pGetDiskIdStr(InputContext, DiskID, StrDiskID, sizeof(StrDiskID)); fprintf(OutFile,"d%s,%s\n",StrDiskID,line); } } else { fprintf(stderr,"A line in section %ws has no key\n",InputSectionName); return(FALSE); } } while(SetupFindNextLine(&InputContext,&InputContext)); } else { fprintf(stderr,"Section %ws is empty or missing\n",InputSectionName); return(FALSE); } return(TRUE); } BOOL DoIt( IN char *InFilename, IN char *FilterFilename, IN DWORD DiskID, IN FILE *OutFile, IN FILE *ExcludeFile, IN char *PlatformExtension, IN FILE *TempFile ) { PCWSTR inFilename; PCWSTR filterFilename; PCWSTR extension; HINF hInputinf, hFilterinf; BOOL b; WCHAR sectionName[256]; INFCONTEXT Ctxt; b = FALSE; inFilename = pSetupAnsiToUnicode(InFilename); filterFilename = pSetupAnsiToUnicode(FilterFilename); // // Only proceed if we've got a file to work with. // if( inFilename ) { // // Only proceed if we've got a filter file to work with. // if( filterFilename ) { hInputinf = SetupOpenInfFileW(inFilename,NULL,INF_STYLE_WIN4,NULL); if(hInputinf != INVALID_HANDLE_VALUE) { // // If the filter-file fails, just keep going. This will // result in a big dosnet.inf, which means we'll have files // present both inside and outside the driver CAB, but // that's not fatal. // hFilterinf = SetupOpenInfFileW(filterFilename,NULL,INF_STYLE_WIN4,NULL); if(hFilterinf == INVALID_HANDLE_VALUE) { fprintf(stderr,"Unable to open inf file %s\n",FilterFilename); hFilterinf = NULL; } // // We're actually ready to process the sections! // fprintf(OutFile,"[Files]\n"); if (ExcludeFile) { fprintf(ExcludeFile,"[Version]\n"); fprintf(ExcludeFile,"signature=\"$Windows NT$\"\n"); fprintf(ExcludeFile,"[Files]\n"); } b = DoSection( hInputinf, L"SourceDisksFiles", hFilterinf, DiskID, OutFile, ExcludeFile, TempFile ); if( b ) { // // Now process the x86-or-Alpha-specific section. // if(extension = pSetupAnsiToUnicode(PlatformExtension)) { lstrcpyW(sectionName,L"SourceDisksFiles"); lstrcatW(sectionName,L"."); lstrcatW(sectionName,extension); b = DoSection( hInputinf, sectionName, hFilterinf, DiskID, OutFile, ExcludeFile, TempFile ); pSetupFree(extension); } else { fprintf(stderr,"Unable to convert string %s to Unicode\n",PlatformExtension); } } //Write the files in the input exclude INF to the [ForceCopyDriverCabFiles] section if (hExclusionInf != INVALID_HANDLE_VALUE) { WCHAR Filename[LINE_LEN]; UCHAR line[MAX_INF_STRING_LENGTH]; if (SetupFindFirstLineW(hExclusionInf, L"Files", NULL, &Ctxt)){ fprintf(OutFile,"\n\n[ForceCopyDriverCabFiles]\n"); do{ if( SetupGetStringFieldW( &Ctxt, 1, Filename, LINE_LEN, NULL )){ // // Dosnet.inf is in OEM chars. // WideCharToMultiByte( CP_OEMCP, 0, Filename, -1, line, sizeof(line), NULL, NULL ); fprintf(OutFile,"%s\n",line); } }while( SetupFindNextLine( &Ctxt, &Ctxt )); }else{ fprintf(stderr,"Could not find the Files section in the Exclude INF file\n"); } } // // Print Statistics... // fprintf( stderr, " Total lines processed: %6d\n", ProcessedLines ); fprintf( stderr, " Entries removed via filter file: %6d\n", RemovedEntries ); fprintf( stderr, "Entries appearing both inside and outside driver CAB: %6d\n", DuplicateEntries ); fprintf( stderr, " Entries not appearing in filter file: %6d\n", PassThroughEntries ); // // Close up our inf handles. // if( hFilterinf ) { SetupCloseInfFile( hFilterinf ); } SetupCloseInfFile(hInputinf); } else { fprintf(stderr,"Unable to open inf file %s\n",InFilename); } pSetupFree( filterFilename ); } else { fprintf(stderr,"Unable to convert filename %s to Unicode\n",FilterFilename); } pSetupFree(inFilename); } else { fprintf(stderr,"Unable to convert filename %s to Unicode\n",InFilename); return(FALSE); } return(b); } int __cdecl main( IN int argc, IN char *argv[] ) { FILE *OutputFile,*ExcludeFile, *TempFile; BOOL b; DWORD DiskID; char input_filename_fullpath[MAX_PATH]; char *p; // // Assume failure. // b = FALSE; if(!pSetupInitializeUtils()) { return FAILURE; } if(ParseArgs(argc,argv)) { // // Open the output file. // OutputFile = fopen(argv[4],"wt"); if (argc >= 7) { ExcludeFile = fopen(argv[6],"wt"); } else { ExcludeFile = NULL; } if (argc >= 8) { hExclusionInf = SetupOpenInfFileA(argv[7],NULL,INF_STYLE_WIN4,NULL); if (hExclusionInf != INVALID_HANDLE_VALUE) { fprintf(stderr,"xdosnet: Opened file %s\n",argv[7]); } } else { hExclusionInf = INVALID_HANDLE_VALUE; } if (argc >= 9) { TempFile = fopen(argv[8],"wt"); if( !TempFile ) fprintf(stderr,"%s: Unable to create temp file %s\n",argv[0],argv[8]); //fprintf(stderr,"xdosnet: Created file %s\n",argv[8]); }else{ TempFile = NULL; } // Special case handling Disk 1, Disk 2 etc. for x86. Since we want to process // all lines - this just means ignore the disk id specified on the command line // and pick up the Disk ID that is specified in the layout.inx entry itself. if ( argv[3][0] == '*' ) DiskID = -1; else DiskID = atoi(argv[3]); GetFullPathName( argv[1], sizeof(input_filename_fullpath), input_filename_fullpath, &p); if(OutputFile) { fprintf( stdout, "%s: creating %s from %s and %s for %s (%s)\n", argv[0], argv[4], input_filename_fullpath, argv[2], argv[5], argv[6]); b = DoIt( input_filename_fullpath, argv[2], DiskID, OutputFile, ExcludeFile, argv[5], TempFile); fclose(OutputFile); } else { fprintf(stderr,"%s: Unable to create output file %s\n",argv[0],argv[3]); } if (ExcludeFile) { fclose(ExcludeFile); } if (TempFile) { fclose(TempFile); } } else { fprintf( stderr,"Merge 3 inf files. Usage:\n" ); fprintf( stderr,"%s \n", argv[0] ); fprintf( stderr,"\n" ); fprintf( stderr," - original inf file (i.e. layout.inf)\n" ); fprintf( stderr," - contains a list of entries to be excluded\n" ); fprintf( stderr," from the final output file\n" ); fprintf( stderr," - output disk id (i.e. 1 or 2)\n" ); fprintf( stderr," - output inf (i.e. dosnet.inf)\n" ); fprintf( stderr," \n" ); fprintf( stderr," - optional output file containing files that were filtered\n" ); fprintf( stderr," - optional input inf containing files that should never be filtered\n" ); fprintf( stderr," - optional file to be used to write boot file list into (IA64 temporary workaround)\n"); fprintf( stderr,"\n" ); fprintf( stderr,"\n" ); } pSetupUninitializeUtils(); return(b ? SUCCESS : FAILURE); }