windows-nt/Source/XPSP1/NT/base/ntsetup/bom/general/general.c
2020-09-26 16:20:57 +08:00

459 lines
12 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include "general.h"
extern FILE* logFile;
#define PLATFORM_COUNT 2
#define X86_PLATFORM 1 // index #2 into PSTR's below.
PSTR GenericSubstitutions[PLATFORM_COUNT] = { "alpha","i386" };
PSTR PlatformSubstitutions[PLATFORM_COUNT] = { "alpha", "x86" };
PSTR AclpathSubstitutions[PLATFORM_COUNT] = { "w32alpha","w32x86" };
typedef struct _TRACKED_STRING {
struct _TRACKED_STRING *Next;
PSTR String;
} TRACKED_STRING, *PTRACKED_STRING;
PTRACKED_STRING SourceFieldStrings;
PTRACKED_STRING PathFieldStrings;
PTRACKED_STRING PlatformFieldStrings;
PTRACKED_STRING CdPathFieldStrings;
PTRACKED_STRING InfFileFieldStrings;
PTRACKED_STRING InfSectionFieldStrings;
PTRACKED_STRING AclPathFieldStrings;
VOID
ExpandField(
IN OUT PSTR *Field,
IN PSTR SubstituteText,
IN OUT PTRACKED_STRING *StringList
)
{
unsigned c;
PSTR p;
CHAR buf[1000];
PTRACKED_STRING s;
if(p = strchr(*Field,'@')) {
c = (unsigned)(p - (*Field));
//
// Create the platform-specific string.
//
strncpy(buf,*Field,c);
buf[c] = 0;
strcat(buf,SubstituteText);
strcat(buf,(*Field) + c + 1);
} else {
//
// No @, field doesn't need to change.
//
return;
}
//
// See whether we already have this string.
//
s = *StringList;
while(s) {
if(!_stricmp(buf,s->String)) {
*Field = s->String;
return;
}
s = s->Next;
}
//
// We don't already have it. Create it.
//
s = malloc(sizeof(TRACKED_STRING));
if(!s) {
PRINT1("ERROR Couldn't allocate enough memory.\n")
exit(1);
}
s->String = _strdup(buf);
if(!s->String) {
PRINT1("ERROR Couldn't allocate enough memory.\n")
exit(1);
}
*Field = s->String;
s->Next = *StringList;
*StringList = s;
}
VOID
ExpandPlatformIndependentEntry(
IN OUT Entry *e,
IN int FirstRecord
)
{
int i,j;
Entry t;
t = *(e+FirstRecord);
for(i=0,j=FirstRecord; i<PLATFORM_COUNT; i++,j++) {
*(e+j) = t;
//
// expand the source field.
//
ExpandField(&e[j].source,PlatformSubstitutions[i],&SourceFieldStrings);
//
// expand the path field.
//
ExpandField(&e[j].path,GenericSubstitutions[i],&PathFieldStrings);
//
// expand the platform field.
//
ExpandField(&e[j].platform,PlatformSubstitutions[i],&PlatformFieldStrings);
//
// expand the cdpath field.
//
ExpandField(&e[j].cdpath,GenericSubstitutions[i],&CdPathFieldStrings);
//
// expand the inf file field.
//
ExpandField(&e[j].inf,GenericSubstitutions[i],&InfFileFieldStrings);
//
// expand the inf section field.
//
ExpandField(&e[j].section,GenericSubstitutions[i],&InfSectionFieldStrings);
//
// expand the aclpath section field.
//
ExpandField(&e[j].aclpath,AclpathSubstitutions[i],&AclPathFieldStrings);
}
}
VOID
ExpandPlatformEntryX86Only(
IN OUT Entry *e,
IN int FirstRecord
)
{
int i,j;
Entry t;
t = *(e+FirstRecord);
i = X86_PLATFORM;
j = FirstRecord;
*(e+j) = t;
//
// expand the source field.
//
ExpandField(&e[j].source,PlatformSubstitutions[i],&SourceFieldStrings);
//
// expand the path field.
//
ExpandField(&e[j].path,GenericSubstitutions[i],&PathFieldStrings);
//
// expand the platform field.
//
ExpandField(&e[j].platform,PlatformSubstitutions[i],&PlatformFieldStrings);
//
// expand the cdpath field.
//
ExpandField(&e[j].cdpath,GenericSubstitutions[i],&CdPathFieldStrings);
//
// expand the inf file field.
//
ExpandField(&e[j].inf,GenericSubstitutions[i],&InfFileFieldStrings);
//
// expand the inf section field.
//
ExpandField(&e[j].section,GenericSubstitutions[i],&InfSectionFieldStrings);
//
// expand the aclpath section field.
//
ExpandField(&e[j].aclpath,AclpathSubstitutions[i],&AclPathFieldStrings);
}
void LoadFile(name,buf,e,records,product)
char* name;
char** buf;
Entry** e;
int* records;
char* product;
{
int match,i;
HANDLE h;
DWORD size,sizeRead,x;
BOOL result;
char* j;
(*records)=0;
h=CreateFile(name,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
size=GetFileSize(h,NULL);
if ((h==INVALID_HANDLE_VALUE) || (size==-1))
{
PRINT2("ERROR Couldn't open %s for reading.\n",name)
exit(1);
}
if (((*buf)=malloc(size))==NULL)
{
PRINT1("ERROR Couldn't allocate enough memory to read file.\n")
exit(1);
}
result=ReadFile(h,*buf,size,&sizeRead,NULL);
if ((sizeRead!=size) || (result==FALSE))
{
PRINT2("ERROR Couldn't read all of %s.\n",name)
exit(1);
}
x=0; while((*buf)[x++]!='\n');
while(x<size) {
if ((*buf)[x]=='\t') (*buf)[x]='\0';
if ((*buf)[x]=='\n') (*records)++;
x++;
}
CloseHandle(h);
//
// Allocate maximum possible number of entries required.
//
if (((*e)=malloc(PLATFORM_COUNT*sizeof(Entry)*(*records)))==NULL) {
PRINT1("ERROR Couldn't allocate enough space for database entries.\n")
exit(1);
}
j=(*buf);
while (*j++!='\n');
match=0;
for (i=0;i<(*records);i++) {
(*e)[match].name=j; while ((*j!='\n') && (*j++));
(*e)[match].source=j; while ((*j!='\n') && (*j++));
(*e)[match].path=j; while ((*j!='\n') && (*j++));
(*e)[match].flopmedia=j; while ((*j!='\n') && (*j++));
(*e)[match].comment=j; while ((*j!='\n') && (*j++));
(*e)[match].product=j; while ((*j!='\n') && (*j++));
(*e)[match].sdk=j; while ((*j!='\n') && (*j++));
(*e)[match].platform=j; while ((*j!='\n') && (*j++));
(*e)[match].cdpath=j; while ((*j!='\n') && (*j++));
(*e)[match].inf=j; while ((*j!='\n') && (*j++));
(*e)[match].section=j; while ((*j!='\n') && (*j++));
(*e)[match].infline=j; while ((*j!='\n') && (*j++));
(*e)[match].size=atoi(j); while((*j!='\n') && (*j++));
(*e)[match].csize=atoi(j); while((*j!='\n') && (*j++));
(*e)[match].nocompress=j; while ((*j!='\n') && (*j++));
(*e)[match].priority=atoi(j); while ((*j!='\n') && (*j++));
(*e)[match].lmacl=j; while ((*j!='\n') && (*j++));
(*e)[match].ntacl=j; while ((*j!='\n') && (*j++));
(*e)[match].aclpath=j; while ((*j!='\n') && (*j++));
(*e)[match].medianame=j; while ((*j!='\n') && (*j++));
(*e)[match].disk=atoi(j); while ((*j!='\n') && (*j++));
j++;
(*e)[match].name=_strupr((*e)[match].name);
(*e)[match].medianame=_strupr((*e)[match].medianame);
if (EntryMatchProduct(&((*e)[match]),product)) {
//
// If this is a platform-independent entry,
// expand it into one entry per platform.
//
if(((*e)[match].platform[0] == '@')
|| ((*e)[match].source[0] == '@')
|| ((*e)[match].cdpath[1] == '@'))
{
// If we are working with x86 floppies,
// just expand for x86, no need for overhead with
// other platforms.
//
if ( !_stricmp(product,"LMFLOP") ||
!_stricmp(product,"NTFLOP") ) {
PRINT2( "%s: Expanding ONLY for X86 flops...\n", (*e)[match].name );
ExpandPlatformEntryX86Only( *e, match );
++match;
}
else {
ExpandPlatformIndependentEntry(*e,match);
match += PLATFORM_COUNT;
}
} else {
// The data is ok as is here.
match++;
}
}
}
//
// Skip first line (column headings).
//
j=*buf;
while (*j++!='\n');
//
// Change newlines into line terminators,
// so the final field on each line will be terminated properly.
//
while(*records) {
if((*j)=='\n') {
*j='\0';
(*records)--;
}
j++;
}
//
// Shrink the array of records to its actual size.
//
*e = realloc(*e,match*sizeof(Entry));
(*records)=match;
}
void EntryPrint(entry,f)
Entry* entry;
FILE *f;
{
fprintf(f,"%s\t",entry->name);
fprintf(f,"%s\t",entry->source);
fprintf(f,"%s\t",entry->path);
fprintf(f,"%s\t",entry->flopmedia);
fprintf(f,"%s\t",entry->comment);
fprintf(f,"%s\t",entry->product);
fprintf(f,"%s\t",entry->sdk);
fprintf(f,"%s\t",entry->platform);
fprintf(f,"%s\t",entry->cdpath);
fprintf(f,"%s\t",entry->inf);
fprintf(f,"%s\t",entry->section);
fprintf(f,"%s\t",entry->infline);
fprintf(f,"%d\t",entry->size);
fprintf(f,"%d\t",entry->csize);
fprintf(f,"%s\t",entry->nocompress);
fprintf(f,"%d\t",entry->priority);
fprintf(f,"%s\t",entry->lmacl);
fprintf(f,"%s\t",entry->ntacl);
fprintf(f,"%s\t",entry->aclpath);
fprintf(f,"%s\t",entry->medianame);
fprintf(f,"%d\r\n",entry->disk);
}
int EntryMatchProduct(entry,product)
Entry* entry;
char* product;
{
if (!_stricmp(product,"ALL"))
return(1);
return
//
// Laying out NT floppies AND entry is not for AS-only
// AND entry specifies that this file goes on floppy
//
(!_stricmp(product,"NTFLOP") // include X86 floppy files
&& _stricmp(entry->product,"as") // exclude AS only files
&& (entry->priority < 1000) // include prioty < 1000
&& _stricmp(entry->source,"alphabins") // exclude alphabins files
&& _stricmp(entry->path,"\\alpha") // exclude alpha path files
&& _stricmp(entry->source,"alphadbg") // exclude alphadbg files
&& _stricmp(entry->source,"x86dbg") // exclude x86dbg files
)
//
// Laying out AS floppies AND entry is not for NT-only
// AND entry specified that this file goes on floppy
//
|| (!_stricmp(product,"LMFLOP")
&& _stricmp(entry->product,"nt") // exclude NT only files
&& (entry->priority < 1000)
&& _stricmp(entry->source,"alphabins")
&& _stricmp(entry->path,"\\alpha")
&& _stricmp(entry->source,"alphadbg")
&& _stricmp(entry->source,"x86dbg")
)
//
// Laying out nt cd-rom and entry is not for as only
//
|| (!_stricmp(product,"NTCD") && _stricmp(entry->product,"as"))
//
// Laying out as cd-rom and entry is not for nt only
//
|| (!_stricmp(product,"LMCD") && _stricmp(entry->product,"nt"))
//
// Laying out sdk
//
|| (!_stricmp(product,"SDK") && !_stricmp(entry->sdk,"x"));
}
int MyOpenFile(f,fileName,mode)
FILE** f;
char* fileName;
char* mode;
{
if ((*f=fopen(fileName,mode))==NULL)
{
PRINT3("ERROR Couldn't open %s for %s\n",fileName,mode)
return(1);
}
return(0);
}
void convertName(oldName,newName)
char* oldName;
char* newName;
{
unsigned i;
unsigned period;
strcpy(newName,oldName);
for (period=(unsigned)(-1),i=0;i<strlen(oldName);i++) if (oldName[i]=='.') period=i;
if (period==(strlen(oldName)-4))
newName[strlen(newName)-1]='_';
else if (period==(unsigned)(-1))
strcat(newName,"._");
else
strcat(newName,"_");
}