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
660 lines
18 KiB
/*++
|
|
|
|
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 <windows.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <setupapi.h>
|
|
#include <sputils.h>
|
|
|
|
|
|
//
|
|
// 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 <input file1> <filter file> <diskid> <output file> <platform extension> <optional output exclude file> <optional input exclusion inf>\n", argv[0] );
|
|
fprintf( stderr,"\n" );
|
|
fprintf( stderr," <input file1> - original inf file (i.e. layout.inf)\n" );
|
|
fprintf( stderr," <filter file> - contains a list of entries to be excluded\n" );
|
|
fprintf( stderr," from the final output file\n" );
|
|
fprintf( stderr," <disk id> - output disk id (i.e. 1 or 2)\n" );
|
|
fprintf( stderr," <output file> - output inf (i.e. dosnet.inf)\n" );
|
|
fprintf( stderr," <platform extension>\n" );
|
|
fprintf( stderr," <output exclude file> - optional output file containing files that were filtered\n" );
|
|
fprintf( stderr," <input exclusion inf> - optional input inf containing files that should never be filtered\n" );
|
|
fprintf( stderr," <temp file> - 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);
|
|
}
|
|
|