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

/*++
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);
}