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

1174 lines
28 KiB
C

/*
xx.xx.94 TedM Created.
10.31.94 JoeHol Added -b switch to help notify of files that
have had bug fixes back-out, eg. since media
build group uses -d switch, we need to know
if a file is now "older" than before so we can
also take the "bad newer" file out of the media.
Also, verifies src and dst by DOS date and time.
11.01.94 JoeHol -l logs to chk.log, not compress.log.
12.14.94 JoeHol Make -l work with name of log file, use dcomp.log
if not specified.
02.07.95 JoeHol -b for bom file. If this is specified we will
check that the files are listed in the bom.
If a file isn't in the bom, we won't add the file
to the list of files to compress.
06.20.95 JoeHol Since we are changing the location of the files,
lets just compressed all, ie. disable real use of the -b switch
for awhile.
08.03.95 JoeHol If a file isn't found to compress in a directory, we don't stop, but
continue gracefully displaying an error message.
*/
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <setupapi.h>
#include <process.h>
typedef struct _SOURCEFILE {
struct _SOURCEFILE *Next;
WIN32_FIND_DATA FileData;
} SOURCEFILE, *PSOURCEFILE;
PSOURCEFILE SourceFileList;
DWORD SourceFileCount;
PSTR SourceSpec,TargetDirectory;
HANDLE NulHandle;
CRITICAL_SECTION SourceListCritSect;
CRITICAL_SECTION ConsoleCritSect;
#define MFL 256
FILE * logFile;
FILE * bomFile;
char logFileName[MFL];
char bomFileName[MFL];
char infFilePath[MFL];
#define MAX_NUMBER_OF_FILES 5000 // let's assume we only have 5000 files max in the product.
#define NAME_SIZE 25 // assume no filename is greater than 25 chars long.
char szFiles[MAX_NUMBER_OF_FILES][NAME_SIZE];
BOOL bVerbose = FALSE;
BOOL bBomChecking = FALSE;
int wRecords=0;
DWORD ThreadCount;
#define MAX_EXCLUDE_EXTENSION 100
PSTR ExcludeExtension[MAX_EXCLUDE_EXTENSION];
unsigned ExcludeExtensionCount;
#define MAX_EXCLUDE_FILEFILTER 100
char ExcludeFileFilter[MAX_EXCLUDE_FILEFILTER][MAX_PATH];
unsigned ExcludeFileFilterCount;
HINF ExcludeFilterHandle[MAX_EXCLUDE_FILEFILTER];
PVOID
MALLOC(
IN DWORD Size
)
{
return((PVOID)LocalAlloc(LMEM_FIXED,Size));
}
VOID
FREE(
IN PVOID Block
)
{
LocalFree((HLOCAL)Block);
}
BOOL
AddExtensionToExclude(
IN PSTR Extension
)
{
//
// Make sure it starts with a dot.
//
if((*Extension != '.') || (lstrlen(Extension) < 2)) {
return(FALSE);
}
if(ExcludeExtensionCount < MAX_EXCLUDE_EXTENSION) {
ExcludeExtension[ExcludeExtensionCount++] = Extension;
} else {
printf("Warning: exclude extension %s ignored (%u max).\n",Extension,MAX_EXCLUDE_EXTENSION);
}
return(TRUE);
}
BOOL
AddFilterToExclude(
IN PSTR FilterName
)
{
DWORD error;
if(!FilterName) {
return(FALSE);
}
if(ExcludeFileFilterCount < MAX_EXCLUDE_EXTENSION) {
ExcludeFilterHandle[ExcludeFileFilterCount] = SetupOpenInfFile(
FilterName,
NULL,
INF_STYLE_WIN4,
&error );
if (ExcludeFilterHandle[ExcludeFileFilterCount] == INVALID_HANDLE_VALUE) {
printf("Warning: couldn't open exclude file filter %s (%d).\n", FilterName , error);
return(FALSE);
}
strcpy( ExcludeFileFilter[ExcludeFileFilterCount], FilterName );
ExcludeFileFilterCount += 1;
return(TRUE);
} else {
printf("Warning: exclude file filter %s ignored (%u max).\n",FilterName,MAX_EXCLUDE_EXTENSION);
}
return(TRUE);
}
BOOL
ParseArguments(
IN int argc,
IN PSTR *argv
)
{
HANDLE FindHandle;
WIN32_FIND_DATA FindData;
while(argc--) {
if((**argv == '-') || (**argv == '/')) {
switch((*argv)[1]) {
case 'b':
case 'B':
strcpy ( infFilePath, &(*argv)[2] );
printf ( "infFilePath: >>>%s<<<\n", &(*argv)[2] );
bBomChecking = TRUE;
break;
case 'l':
case 'L':
strcpy ( logFileName, &(*argv)[2] );
//printf ( ">>>%s<<<\n", &(*argv)[2] );
break;
case 'm':
case 'M':
if(ThreadCount) {
return(FALSE);
}
ThreadCount = (DWORD)atoi((*argv)+2);
if(!ThreadCount) {
return(FALSE);
}
break;
case 'v':
case 'V':
bVerbose = TRUE;
break;
case 'x':
case 'X':
if((argc-- < 1) || !AddExtensionToExclude(*(++argv))) {
return(FALSE);
}
break;
case 'f':
case 'F':
if((argc-- < 1) || !AddFilterToExclude(*(++argv))) {
return(FALSE);
}
break;
default:
return(FALSE);
}
} else {
if(SourceSpec) {
if(TargetDirectory) {
return(FALSE);
} else {
TargetDirectory = *argv;
}
} else {
SourceSpec = *argv;
}
}
argv++;
}
if(!TargetDirectory || !SourceSpec) {
return(FALSE);
}
//
// Make sure target is a directory.
//
FindHandle = FindFirstFile(TargetDirectory,&FindData);
if(FindHandle == INVALID_HANDLE_VALUE) {
return(FALSE);
}
FindClose(FindHandle);
if(!(FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
return(FALSE);
}
return(TRUE);
}
VOID
Usage(
VOID
)
{
printf("DCOMP -llog [-x .ext ...] [-m#] [-d] [-bbom] Source Dest\n\n");
printf(" -x .ext Exclude files with extension .ext.\n");
printf(" -m Force use of # threads.\n");
printf(" -v Verbose.\n" );
printf(" -llog Log filename, dcomp.log default.\n");
printf(" -binfPath your setup\\inf\\win4\\inf path.\n" );
printf(" -f infname Excludes files listed in inf.\n");
printf(" Source Source file specification. Wildcards may be used.\n");
printf(" Destination Specifies directory where renamed compressed files\n");
printf(" will be placed.\n");
}
VOID
DnpGenerateCompressedName(
IN PSTR Filename,
OUT PSTR CompressedName
)
/*++
Routine Description:
Given a filename, generate the compressed form of the name.
The compressed form is generated as follows:
Look backwards for a dot. If there is no dot, append "._" to the name.
If there is a dot followed by 0, 1, or 2 charcaters, append "_".
Otherwise assume there is a 3-character extension and replace the
third character after the dot with "_".
Arguments:
Filename - supplies filename whose compressed form is desired.
CompressedName - receives compressed file name.
Return Value:
None.
--*/
{
PSTR p,q;
strcpy(CompressedName,Filename);
p = strrchr(CompressedName,'.');
q = strrchr(CompressedName,'\\');
if(q < p) {
//
// If there are 0, 1, or 2 characters after the dot, just append
// the underscore. p points to the dot so include that in the length.
//
if(lstrlen(p) < 4) {
lstrcat(CompressedName,"_");
} else {
//
// Assume there are 3 characters in the extension. So replace
// the final one with an underscore.
//
p[3] = '_';
}
} else {
//
// No dot, just add ._.
//
lstrcat(CompressedName,"._");
}
}
BOOL
GetSetTimeStamp(
IN PSTR FileName,
OUT PFILETIME CreateTime,
OUT PFILETIME AccessTime,
OUT PFILETIME WriteTime,
IN BOOL Set
)
{
HANDLE h;
BOOL b;
//
// Open the file.
//
h = CreateFile(
FileName,
Set ? GENERIC_WRITE : GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
0,
NULL
);
if(h == INVALID_HANDLE_VALUE) {
return(FALSE);
}
b = Set
? SetFileTime(h,CreateTime,AccessTime,WriteTime)
: GetFileTime(h,CreateTime,AccessTime,WriteTime);
CloseHandle(h);
return(b);
}
VOID
mprintf(
IN DWORD ThreadSerialNumber,
IN PSTR FormatString,
...
)
{
CHAR msg[2048];
va_list arglist;
va_start(arglist,FormatString);
vsprintf(msg,FormatString,arglist);
vfprintf(logFile,FormatString,arglist); // print to log file
va_end(arglist);
//EnterCriticalSection(&ConsoleCritSect);
if(ThreadCount == 1) {
printf(msg);
} else {
printf("%u: %s",ThreadSerialNumber,msg);
}
//LeaveCriticalSection(&ConsoleCritSect);
}
VOID
logprintf(
IN PSTR FormatString,
...
)
{
CHAR msg[2048];
va_list arglist;
va_start(arglist,FormatString);
vsprintf(msg,FormatString,arglist);
vfprintf(logFile,FormatString,arglist); // print to log file
va_end(arglist);
}
// SameDosDateTime returns: TRUE if date/times are same; FALSE otherwise.
//
BOOL
SameDosDateTime(
IN DWORD ThreadSerialNumber,
IN PSTR SourceFileName,
IN PSTR DestFileName,
IN BOOL bDstMustExistNow
)
{
HANDLE h;
FILETIME ftSourceWriteTime;
FILETIME dftDestWriteTime;
FILETIME CreateTime, AccessTime;
FILETIME dCreateTime, dAccessTime;
WORD srcDate, dstDate, srcTime, dstTime; // DOS versions.
//
// Open the source file.
//
h = CreateFile(
SourceFileName,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
0,
NULL
);
if(h == INVALID_HANDLE_VALUE) {
mprintf ( ThreadSerialNumber, "ERROR CreateFile: %s, gle = %ld\n",
SourceFileName, GetLastError() );
return(FALSE);
}
GetFileTime(h,&CreateTime,&AccessTime,&ftSourceWriteTime);
CloseHandle(h);
FileTimeToDosDateTime ( &ftSourceWriteTime, &srcDate, &srcTime );
//
// Open the destination file.
//
h = CreateFile(
DestFileName,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
0,
NULL
);
if(h == INVALID_HANDLE_VALUE) {
if ( bDstMustExistNow ) {
// In case we get something like, FILE_NOT_FOUND
//
mprintf ( ThreadSerialNumber,
"ERROR CreateFile: dst %s, gle = %ld\n",
DestFileName,GetLastError());
}
return(FALSE);
}
GetFileTime(h,&dCreateTime,&dAccessTime,&dftDestWriteTime);
CloseHandle(h);
FileTimeToDosDateTime ( &dftDestWriteTime, &dstDate, &dstTime );
// Compare that the DOS date and times are the same.
//
if ( (srcDate != dstDate) || (srcTime != dstTime) ) {
if ( 1 /*bVerbose*/ ) {
mprintf ( ThreadSerialNumber,
"Warning, times different: %s = %x-%x, %s = %x-%x\n",
SourceFileName,
srcDate, srcTime,
DestFileName,
dstDate, dstTime );
}
return (FALSE);
}
return (TRUE); // DOS dates and times are the same.
}
DWORD
WorkerThread(
IN PVOID ThreadParameter
)
{
PSOURCEFILE SourceFile;
DWORD ThreadSerialNumber;
CHAR FullSourceName[2*MAX_PATH];
CHAR FullTargetName[2*MAX_PATH];
CHAR CompressedName[2*MAX_PATH];
CHAR CmdLine[5*MAX_PATH];
PCHAR p;
STARTUPINFO StartupInfo;
PROCESS_INFORMATION ProcessInfo;
BOOL b;
DWORD d;
int i;
ThreadSerialNumber = PtrToUlong(ThreadParameter);
ZeroMemory(&StartupInfo,sizeof(StartupInfo));
StartupInfo.cb = sizeof(STARTUPINFO);
while(1) {
//
// Pluck the next source file off the list.
// If there is no next source file, we're done.
//
EnterCriticalSection(&SourceListCritSect);
SourceFile = SourceFileList;
if(!SourceFile) {
LeaveCriticalSection(&SourceListCritSect);
return(TRUE);
}
SourceFileList = SourceFile->Next;
LeaveCriticalSection(&SourceListCritSect);
//
// Form the source file name.
//
lstrcpy(FullSourceName,SourceSpec);
if(p = strrchr(FullSourceName,'\\')) {
p++;
} else {
p = FullSourceName;
}
lstrcpy(p,SourceFile->FileData.cFileName);
//
// Form full target name.
//
lstrcpy(FullTargetName,TargetDirectory);
i = lstrlen(FullTargetName);
if(FullTargetName[i-1] != '\\') {
FullTargetName[i] = '\\';
FullTargetName[i+1] = 0;
}
lstrcat(FullTargetName,SourceFile->FileData.cFileName);
DnpGenerateCompressedName(FullTargetName,CompressedName);
//
// If the update flag is set, check timestamps.
// If this fails, assume the target file does not exist.
//
if ( !SameDosDateTime ( ThreadSerialNumber,
FullSourceName,
CompressedName, FALSE ) ) {
//
// Form the command line for the child process.
//
sprintf(CmdLine,"diamond /D CompressionType=LZX /D CompressionMemory=21 %s %s",FullSourceName,CompressedName);
if ( 1 /*bVerbose*/ ) {
mprintf(ThreadSerialNumber,
"Start %s ==> %s\n",FullSourceName,CompressedName);
}
//
// Invoke the child process.
//
b = CreateProcess(
NULL,
CmdLine,
NULL,
NULL,
FALSE,
DETACHED_PROCESS,
NULL,
NULL,
&StartupInfo,
&ProcessInfo
);
if(b) {
CloseHandle(ProcessInfo.hThread);
//
// Wait for the child process to terminate and get its
// return code.
//
WaitForSingleObject(ProcessInfo.hProcess,INFINITE);
b = GetExitCodeProcess(ProcessInfo.hProcess,&d);
CloseHandle(ProcessInfo.hProcess);
if(b) {
//
// 'd' value of 0 means success, we've compressed the
// file. Now, set the time stamp on the target file.
//
if(d) {
// 'd' not 0, error occurred.
//
mprintf(ThreadSerialNumber,"ERROR compressing %s to %s.\n",FullSourceName,CompressedName);
} else {
// 'd' is 0, we compressed the file, now time stamp.
//
// First get the source time's stamp.
//
GetSetTimeStamp(
FullSourceName,
&SourceFile->FileData.ftCreationTime,
&SourceFile->FileData.ftLastAccessTime,
&SourceFile->FileData.ftLastWriteTime,
FALSE
);
// Now, set the destination time's stamp.
//
GetSetTimeStamp(
CompressedName,
&SourceFile->FileData.ftCreationTime,
&SourceFile->FileData.ftLastAccessTime,
&SourceFile->FileData.ftLastWriteTime,
TRUE
);
// Double check it is really set.
//
if ( SameDosDateTime ( ThreadSerialNumber,
FullSourceName,
CompressedName,
TRUE ) ) {
if ( bVerbose ) {
mprintf(ThreadSerialNumber,"Compressed %s to %s.\n",FullSourceName,CompressedName);
}
} else {
mprintf(ThreadSerialNumber,"ERROR Compressed %s to %s - time stamps don't match.\n",FullSourceName,CompressedName);
}
}
} else {
mprintf(ThreadSerialNumber,"ERROR Unable to get process \"%s\" termination code.\n",CmdLine);
}
} else {
mprintf(ThreadSerialNumber,"ERROR Unable to invoke \"%s\".\n",CmdLine);
}
} else {
if ( bVerbose ) {
mprintf(ThreadSerialNumber,
"%s is up to date.\n",CompressedName);
}
}
}
}
// FileInBom
// Returns TRUE if fileName is located in the BOM; FALSE otherwise.
//
BOOL FileInBom ( char * fileName ) {
int i;
for ( i = 0; i < wRecords; ++i ) {
if ( _stricmp(fileName, szFiles[i] ) == 0 ) {
return(TRUE);
}
}
return(FALSE);
}
// AddSourceFile
// returns FALSE if an error.
// returns TRUE if no error occrred, but not necesarrily meaning a file
// was added.
BOOL
AddSourceFile(
IN PWIN32_FIND_DATA FindData
)
{
static PSOURCEFILE LastFile = NULL;
PSOURCEFILE SourceFile;
unsigned i;
DWORD ExtensionLength;
DWORD FileNameLength;
INFCONTEXT InfContext;
// If we are doing BOM checking, make sure that this file is
// listed in the BOM. If it is, continue on to the next checking.
// If it is NOT, just return.
//
if ( bBomChecking && !FileInBom(FindData->cFileName) ) {
return(TRUE);
}
//
// Make sure this file is not of a type that is
// supposed to be excluded from the list of files
// we care about.
//
FileNameLength = lstrlen(FindData->cFileName);
for(i=0; i<ExcludeExtensionCount; i++) {
ExtensionLength = lstrlen(ExcludeExtension[i]);
if((FileNameLength > ExtensionLength)
&& !lstrcmpi(ExcludeExtension[i],FindData->cFileName+FileNameLength-ExtensionLength)) {
return(TRUE);
}
}
for(i=0; i<ExcludeFileFilterCount; i++) {
if ( SetupFindFirstLine(ExcludeFilterHandle[i],
"Files",
FindData->cFileName,
&InfContext )) {
return(TRUE);
}
}
SourceFile = MALLOC(sizeof(SOURCEFILE));
if(!SourceFile) {
printf("ERROR Insufficient memory.\n");
return(FALSE);
}
SourceFile->FileData = *FindData;
SourceFile->Next = NULL;
if(LastFile) {
LastFile->Next = SourceFile;
} else {
SourceFileList = SourceFile;
}
LastFile = SourceFile;
SourceFileCount++;
return(TRUE);
}
BOOL
FindSourceFiles(
VOID
)
{
WIN32_FIND_DATA FindData;
HANDLE FindHandle;
printf("Building list of source files...\n");
//
// Build a list of source files.
//
FindHandle = FindFirstFile(SourceSpec,&FindData);
if(FindHandle != INVALID_HANDLE_VALUE) {
if(!(FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
if(!AddSourceFile(&FindData)) {
FindClose(FindHandle);
return(FALSE);
}
}
while(FindNextFile(FindHandle,&FindData)) {
if(!(FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
if(!AddSourceFile(&FindData)) {
FindClose(FindHandle);
return(FALSE);
}
}
}
FindClose(FindHandle);
}
if(!SourceFileCount) {
printf("Warning: No files found in: %s.\n",SourceSpec);
}
return(SourceFileCount != 0);
}
VOID
DoIt(
VOID
)
{
SYSTEM_INFO SystemInfo;
PHANDLE ThreadHandles;
DWORD i;
DWORD ThreadId;
//
// Determine number of threads to use.
// This is based on the number of processors.
//
if(!ThreadCount) {
GetSystemInfo(&SystemInfo);
ThreadCount = SystemInfo.dwNumberOfProcessors;
}
ThreadHandles = MALLOC(ThreadCount * sizeof(HANDLE));
if(!ThreadHandles) {
printf("ERROR Insufficient memory.\n");
exit(1);
}
if ( bVerbose ) {
if(ThreadCount == 1) {
printf("Compressing %u files...\n",SourceFileCount);
} else {
printf("Compressing %u files (%u threads)...\n",SourceFileCount,ThreadCount);
}
}
//
// Initialize the source file list critical section.
//
InitializeCriticalSection(&SourceListCritSect);
//
// Create threads.
//
for(i=0; i<ThreadCount; i++) {
ThreadHandles[i] = CreateThread(
NULL,
0,
WorkerThread,
(PVOID)UlongToPtr(i),
0,
&ThreadId
);
}
//
// Wait for the threads to terminate.
//
WaitForMultipleObjects(ThreadCount,ThreadHandles,TRUE,INFINITE);
//
// Clean up and exit.
//
for(i=0; i<ThreadCount; i++) {
CloseHandle(ThreadHandles[i]);
}
FREE(ThreadHandles);
}
#define idALL 0
#define idX86 1
#define idMIPS 2
#define idALPHA 3
#define idPPC 4
#define FILE_SECTION_ALL "[SourceDisksFiles]"
#define FILE_SECTION_X86 "[SourceDisksFiles.x86]"
#define FILE_SECTION_MIPS "[SourceDisksFiles.mips]"
#define FILE_SECTION_ALPHA "[SourceDisksFiles.alpha]"
#define FILE_SECTION_PPC "[SourceDisksFiles.ppc]"
#define FILE_SECTION_NOT_USED 0xFFFF
DWORD dwInsideSection = FILE_SECTION_NOT_USED;
DWORD FigureSection ( char * Line ) {
logprintf ( "FigureSection on: %s\n", Line );
if ( strstr ( Line, FILE_SECTION_ALL ) ) {
dwInsideSection = idALL;
}
else
if ( strstr ( Line, FILE_SECTION_X86 ) ) {
dwInsideSection = idX86;
}
else
if ( strstr ( Line, FILE_SECTION_MIPS ) ) {
dwInsideSection = idMIPS;
}
else
if ( strstr ( Line, FILE_SECTION_ALPHA ) ) {
dwInsideSection = idALPHA;
}
else
if ( strstr ( Line, FILE_SECTION_PPC ) ) {
dwInsideSection = idPPC;
}
else {
dwInsideSection = FILE_SECTION_NOT_USED;
}
logprintf ( "dwInsideSection = %x\n", dwInsideSection );
return(dwInsideSection);
}
char * SuckName ( const char * Line ) {
static char szSuckedName[MFL];
DWORD dwIndex = 0;
// The line is in the form: @@:file = 1,2,3,4,5,6,7,8
//
// Skip the first @.
//
if ( *Line == '@' ) {
++Line;
}
// Skip the 2nd @, w, or s.
//
if ( *Line == '@' || *Line == 'w' || *Line == 's' ) {
++Line;
}
// Skp the :.
//
if ( *Line == ':' ) {
++Line;
}
// Copy the file name until a space is encountered.
//
while ( *Line != ' ' ) {
szSuckedName[dwIndex] = *Line;
szSuckedName[dwIndex+1] = '\0';
++Line;
++dwIndex;
}
return szSuckedName;
}
void LoadFiles ( const char * infFilePath, const char * infFile ) {
FILE * fHandle;
char Line[MFL];
int i;
sprintf ( bomFileName, "%s%s", infFilePath, infFile );
logprintf ( "bomFileName = %s\n", bomFileName );
fHandle = fopen ( bomFileName, "rt" );
if ( fHandle ) {
dwInsideSection = FILE_SECTION_NOT_USED;
while ( fgets ( Line, sizeof(Line), fHandle ) ) {
if ( Line[0] == '[' ) {
// We have a new section.
//
dwInsideSection = FigureSection ( Line );
continue;
}
// Reasons to ignore this line from further processing.
//
//
// File section not one we process.
//
if ( dwInsideSection == FILE_SECTION_NOT_USED ) {
continue;
}
// Line just contains a non-usefull short string.
//
i = strlen ( Line );
if ( i < 4 ) {
continue;
}
// Line contains just a comment.
//
if ( Line[0] == ';' ) {
continue;
}
switch ( dwInsideSection ) {
case idALL :
case idX86 :
case idMIPS :
case idALPHA :
case idPPC :
sprintf ( szFiles[wRecords], "%s", SuckName ( Line ) );
logprintf ( "file = %s\n", szFiles[wRecords] );
++wRecords;
break;
default :
// Not inside any section we need files for compressing.
//
break;
}
}
if ( ferror(fHandle) ) {
mprintf ( 0, "FATAL ERROR: reading from: %s\n", bomFileName );
}
fclose ( fHandle );
}
else {
mprintf ( 0, "FATAL ERROR: Can't fopen(%s)\n", bomFileName );
bBomChecking = FALSE;
}
}
int
__cdecl
main(
IN int argc,
IN char *argv[]
)
{
//
// Skip argv[0]
//
argc--;
argv++;
NulHandle = CreateFile(
"nul",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL
);
if(NulHandle == INVALID_HANDLE_VALUE) {
printf("ERROR Unable to open \\dev\\nul.\n");
return(1);
}
InitializeCriticalSection(&ConsoleCritSect);
strcpy ( logFileName, "dcomp.log" ); // default log filename.
strcpy ( bomFileName, "bom.txt" ); // default bom filename.
if(ParseArguments(argc,argv)) {
logFile = fopen ( logFileName, "a" );
if ( logFile == NULL ) {
printf ( "ERROR Couldn't open logFile.\n" );
exit(1);
}
if ( bBomChecking ) {
// Load Layout.inx and cairo\Layout.cai, _media.inx doesn't contains files we
// need compressed, as of today.
//
LoadFiles ( infFilePath, "\\Layout.inx" );
mprintf ( 0, "bom loaded records: %d\n", wRecords );
}
if(FindSourceFiles()) {
DoIt();
}
} else {
Usage();
}
CloseHandle(NulHandle);
if ( logFile ) {
fclose ( logFile );
}
return (0);
}