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

12 KiB

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <windows.h> #include <time.h> #include "general.h"

#define MAX_DISKS 40

/ / Macro for rounding up any number (x) to multiple of (n) which / must be a power of 2. For example, ROUNDUP( 2047, 512 ) would / yield result of 2048. //

#define ROUNDUP2( x, n ) (((x) + ((n) - 1 )) & ~((n) - 1 ))

FILE* logFile; int cdProduct;

HANDLE hActivateCopyThread, hCopyThreadIsAvailable; CHAR chCopyThreadSource[ MAX_PATH ], chCopyThreadDestin[ MAX_PATH ]; CHAR chPreviousSource[ MAX_PATH ], chPreviousDestin[ MAX_PATH ];

void MakeDbgName( LPCSTR pszSourceName, LPSTR pszTargetName ); void DoThreadedCopy( LPSTR pszSource, LPSTR pszDestin ); DWORD CopyThread( LPVOID lpvParam );

void Msg ( const char * szFormat, … ) {

va_list vaArgs;

va_start ( vaArgs, szFormat ); vprintf ( szFormat, vaArgs ); vfprintf ( logFile, szFormat, vaArgs ); va_end ( vaArgs ); }

void Header(argv) char* argv[]; { time_t t;

Msg ("\n=========== MCPYFILE ===========\n"); Msg ("logfile : %s\n", argv[1] ); Msg ("Input Layout: %s\n",argv[2]); Msg ("category : %s\n",argv[3]); Msg ("Compressed files: %s\n", argv[4]); Msg ("Uncompressed files : %s\n", argv[5]); Msg ("Hard drive: %s\n",argv[6]); Msg ("Copy d-DBG, x-FLOPPY, c-CDROM files: %s\n", argv[7] ); time(&t); Msg ("Time: %s",ctime(&t)); Msg ("================================\n\n"); }

void Usage() { printf("PURPOSE: Copy files to hardrive or into disk1, disk2, … dirs.\n"); printf("\n"); printf("PARAMETERS:\n"); printf("\n"); printf("[logFile] - Path to append a log of actions and errors.\n"); printf("[InLayout] - Path of Layout which lists files to copy.\n"); printf("[Category] - Specifies the category of files to copy.\n"); printf("[files share] - location of Compressed files.\n" ); printf("[files share] - location of Uncompressed files\n" ); printf("[Harddrive] - Drive where files are stored.\n"); printf("[copy dbg,floppy,or cd files] - use D for .dbg files or x for floppy files\n" ); }

int _CRTAPI1 DiskDirCompare(const void*,const void*);

int _CRTAPI1 main(argc,argv) int argc; char* argv[]; { Entry ee; char sourcePath[MAX_PATH]; char destinPath[MAX_PATH]; int disks[MAX_DISKS]; Entry *e; char *buf; int records,i; BOOL shouldCopy; BOOL update; BOOL bCompressedFile; BOOL bCopyDbgFiles; HANDLE hSource,hDestin, hThread; DWORD actualSize,bomSize, dwThreadID; WIN32_FIND_DATA fdSource, fdDestin;

if ( argc != 8 ) { Usage(); return(1); }

if ((logFile=fopen(argv[1],"a"))==NULL) {

printf("ERROR Couldn't open log file %s.\n",argv[1]); return(1); }

hActivateCopyThread = CreateEvent( NULL, FALSE, FALSE, NULL ); hCopyThreadIsAvailable = CreateEvent( NULL, FALSE, TRUE, NULL ); hThread = CreateThread( NULL, 0, CopyThread, NULL, 0, &dwThreadID ); CloseHandle( hThread );

Header(argv);

/ Load all of the current entries in the layout file / provided to the program. // LoadFile(argv[2],&buf,&e,&records,"ALL");

cdProduct = TRUE; bCopyDbgFiles = FALSE; update = TRUE; if ( !stricmp ( "ntflop", argv[3] ) || !stricmp ( "lmflop", argv[3] ) || stricmp ( argv[7], "x" ) == 0 ) {

cdProduct = FALSE; bCopyDbgFiles = FALSE;

Msg ( "Making X86 Floppies…\n" ); } else { Msg ( "Making CDs…\n" ); bCopyDbgFiles = !stricmp( argv[7], "d" ); }

Msg ( "bCopyDbgFiles = %d\n", bCopyDbgFiles ); //qsort(e,records,sizeof(ee),DiskDirCompare);

for (i=0;i<MAX_DISKS;i++) { disks[i]=0; }

for (i=0;i<records;i++) {

if (e[i].cdpath[strlen(e[i].cdpath)-1]=='\\') {

e[i].cdpath[strlen(e[i].cdpath)-1]='\0'; } if (e[i].path[strlen(e[i].path)-1]=='\\') {

e[i].path[strlen(e[i].path)-1]='\0'; }

disks[e[i].disk]++; }

for (i=0;i<records;i++) {

if (!((records-i)%100)) { printf("# files remaining:%5d/%d\n",records-i,records); }

ee=e[i];

if (!stricmp(ee.source,argv[3])) { // if category matches

if ( cdProduct ) {

/ Making CD. / / / It's a compressed file IFF / the nocompress flag is NOT set (i.e. null) AND / we're NOT copying dbg-files. // bCompressedFile = !ee.nocompress[0] && !bCopyDbgFiles;

} else {

/ Making x86 floppies. / / NOTE: in Layout.C, we go back to the convention of: / / "" == yes, compress this file / "x" == no don't compress this file // bCompressedFile = stricmp(ee.nocompress, "x" );

//Msg ( "%s, bCompressedFile = %d\n", ee.name, bCompressedFile );

}

//Msg ( "bCompressedFile = %d, %s\n", bCompressedFile, ee.name );

if ( bCompressedFile ) { strcpy( sourcePath, argv[ 4 ] ); / use compressed path bomSize = ee.csize; / and compressed size } else { strcpy( sourcePath, argv[ 5 ] ); / uncompressed path bomSize = ee.size; / uncompressed size }

strcat(sourcePath,ee.path); strcat(sourcePath,"\\");

if ( bCompressedFile ) { convertName( ee.name, strchr( sourcePath, 0 )); } else if ( bCopyDbgFiles ) { MakeDbgName( ee.name, strchr( sourcePath, 0 )); } else { strcat( sourcePath, ee.name ); }

// May have to massage disk1…disk tagfiles… if ( cdProduct ) { strcpy(destinPath,argv[6]); if ( ! bCopyDbgFiles ) { strcat(destinPath,ee.cdpath); } } else { strcpy(destinPath,argv[6]); sprintf(&destinPath[strlen(destinPath)],"\\disk%d",ee.disk); }

strcat(destinPath,"\\");

if ( bCopyDbgFiles ) { MakeDbgName( ee.name, strchr( destinPath, 0 )); } else { if (ee.medianame[0]) { if ( bCompressedFile ) { convertName( ee.medianame, strchr( destinPath, 0 ));

/ For simplification in the BOM, we no longer / rename compressed files. I.E, any file that has / to be renamed, CANNOT be compressed. / Msg ( "ERROR: renaming compressed file not supported: %s\n", destinPath ); } else { strcat( destinPath, ee.medianame ); } } else { if ( bCompressedFile ) { convertName( ee.name, strchr( destinPath, 0 )); } else { strcat( destinPath, ee.name ); } } }

if (disks[ee.disk]>1) {

/ / Don't attempt to copy same file twice (target file might / not yet completely exist since threaded copy might not be / complete, so can't rely on timestamp equivalence yet). // if ( stricmp( sourcePath, chPreviousSource ) || stricmp( destinPath, chPreviousDestin )) {

hSource=FindFirstFile( sourcePath, &fdSource );

if (hSource==INVALID_HANDLE_VALUE) { Msg ("ERROR Source: %s\n",sourcePath); } else {

FindClose( hSource );

if ( !cdProduct ) { actualSize = ROUNDUP2( fdSource.nFileSizeLow, DMF_ALLOCATION_UNIT ); } else { actualSize = ROUNDUP2( fdSource.nFileSizeLow, ALLOCATION_UNIT ); }

/ Check the size of the file vs. the size in the / bom just for a verification of file sizes. / Don't do this for Dbg files, since these sizes are / never put in the layout. // if ( !bCopyDbgFiles && (bomSize < actualSize) ) { Msg ( "ERROR: disk#%d, %s Size of file: %d > BOM: %d Diff: %d\n", ee.disk,ee.name, actualSize,bomSize,actualSize-bomSize); }

shouldCopy=TRUE;

if (update) {

hDestin=FindFirstFile( destinPath, &fdDestin );

if (hDestin==INVALID_HANDLE_VALUE) { // Msg ("New file %s\n", destinPath); } else { FindClose( hDestin );

if ( CompareFileTime( &fdSource.ftLastWriteTime, &fdDestin.ftLastWriteTime ) <= 0 ) { shouldCopy=FALSE; } else { //Msg ("Updating %s\n",destinPath); }

} }

if (shouldCopy) { Msg ( "Copy: %s >>> %s\n", sourcePath, destinPath); DoThreadedCopy( sourcePath, destinPath ); strcpy( chPreviousSource, sourcePath ); strcpy( chPreviousDestin, destinPath ); } } } } else { Msg ("WARNING Skipped Disk %d, File: %s\n",ee.disk,ee.name); } } } fclose(logFile); WaitForSingleObject( hCopyThreadIsAvailable, INFINITE ); }

int _CRTAPI1 DiskDirCompare(const void *v1, const void *v2) { Entry *e1 = (Entry *)v1; Entry *e2 = (Entry *)v2;

/ / If the files are not on the same disk, / the comparison is easy. / if(e1->disk != e2->disk) { return(e1->disk - e2->disk); }

/ / If this is a cd-rom, sort by location on the cd. // if(cdProduct) { return(stricmp(e1->cdpath,e2->cdpath)); }

/ / Floppy product: we know the files are on the same disk / and files on the floppy are all in the same directory. / return(0); }

void DoThreadedCopy( LPSTR pszSource, LPSTR pszDestin ) { WaitForSingleObject( hCopyThreadIsAvailable, INFINITE ); strcpy( chCopyThreadSource, pszSource ); strcpy( chCopyThreadDestin, pszDestin ); SetEvent( hActivateCopyThread ); }

DWORD CopyThread( LPVOID lpvParam ) {

BOOL bSuccess; UINT i, len;

for(;;) {

WaitForSingleObject( hActivateCopyThread, INFINITE );

bSuccess = CopyFile( chCopyThreadSource, chCopyThreadDestin, FALSE );

if ( ! bSuccess ) {

SetFileAttributes( chCopyThreadDestin, FILE_ATTRIBUTE_NORMAL );

len = strlen( chCopyThreadDestin ); for ( i = 2; i < len; i++ ) { if ( chCopyThreadDestin[ i ] == '\\' ) { chCopyThreadDestin[ i ] = '\0'; CreateDirectory( chCopyThreadDestin, NULL ); chCopyThreadDestin[ i ] = '\\'; } }

bSuccess = CopyFile( chCopyThreadSource, chCopyThreadDestin, FALSE );

}

if ( ! bSuccess ) { Msg ( "ERROR Source: %s\n" " Destin: %s\n" " GLE=%d\n", chCopyThreadSource, chCopyThreadDestin, GetLastError() ); }

SetEvent( hCopyThreadIsAvailable );

}

return 0;

}

void MakeDbgName( LPCSTR pszSourceName, LPSTR pszTargetName ) {

/ / Converts "filename.ext" into "ext\filename.dbg". //

const char *p = strchr( pszSourceName, '.' );

if ( p != NULL ) { strcpy( pszTargetName, p + 1 ); / old extension strcat( pszTargetName, "\\" ); / path separator strcat( pszTargetName, pszSourceName ); / base name strcpy( strchr( pszTargetName, '.' ), ".dbg" ); / new extension } else { strcpy( pszTargetName, pszSourceName ); }

}