886 lines
20 KiB
C
886 lines
20 KiB
C
|
#ifndef COMPILED_FORDOS
|
||
|
#include <nt.h>
|
||
|
#include <ntrtl.h>
|
||
|
#include <nturtl.h>
|
||
|
#endif
|
||
|
#include <windows.h>
|
||
|
#include <dos.h>
|
||
|
#include <stdio.h>
|
||
|
#include <string.h>
|
||
|
#include <stdio.h>
|
||
|
#include <stddef.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <stdarg.h>
|
||
|
#include <limits.h>
|
||
|
#include <malloc.h>
|
||
|
#include <errno.h>
|
||
|
#include <ctype.h>
|
||
|
#include <signal.h>
|
||
|
#include <string.h>
|
||
|
#include <time.h>
|
||
|
#include <io.h>
|
||
|
#include <conio.h>
|
||
|
#include <sys\types.h>
|
||
|
#include <sys\stat.h>
|
||
|
|
||
|
#ifdef COMPILED_FORDOS
|
||
|
#define MAX_PATH 256
|
||
|
#endif
|
||
|
|
||
|
#define READ_BUFFER_SIZE (8192*sizeof(DWORD))
|
||
|
#define CHECK_NAME "\\chkfile.chk"
|
||
|
extern BOOL fUsage;
|
||
|
extern BOOL fGenerateCheck;
|
||
|
extern LPSTR RootOfTree;
|
||
|
char RootBuffer[MAX_PATH];
|
||
|
extern BOOL fVerbose;
|
||
|
LPSTR CheckFileName;
|
||
|
char OutputLine[512];
|
||
|
DWORD ReadBuffer[READ_BUFFER_SIZE/sizeof(DWORD)];
|
||
|
|
||
|
WORD
|
||
|
CheckSum(
|
||
|
DWORD ParitialSum,
|
||
|
LPWORD Source,
|
||
|
DWORD Length
|
||
|
);
|
||
|
|
||
|
|
||
|
typedef struct _FINDBUF {
|
||
|
char reserved[21];
|
||
|
char attrib;
|
||
|
unsigned short wr_time;
|
||
|
unsigned short wr_data;
|
||
|
long size;
|
||
|
char name[13];
|
||
|
} FINDBUF, *PFINDBUF;
|
||
|
|
||
|
DWORD
|
||
|
PortFindFirstFile(
|
||
|
LPSTR FindPattern,
|
||
|
LPSTR FindName,
|
||
|
LPBOOL IsDir,
|
||
|
LPDWORD FindSize
|
||
|
);
|
||
|
BOOL
|
||
|
PortFindNextFile(
|
||
|
DWORD FindHandle,
|
||
|
LPSTR FindName,
|
||
|
LPBOOL IsDir,
|
||
|
LPDWORD FindSize
|
||
|
);
|
||
|
|
||
|
VOID
|
||
|
PortFindClose(
|
||
|
DWORD FindHandle
|
||
|
);
|
||
|
|
||
|
VOID
|
||
|
GenerateCheckFile( VOID );
|
||
|
|
||
|
VOID
|
||
|
ValidateCheckFile( VOID );
|
||
|
|
||
|
BOOL
|
||
|
ProcessParameters(
|
||
|
int argc,
|
||
|
LPSTR argv[]
|
||
|
);
|
||
|
|
||
|
FILE *GlobalCheckFile;
|
||
|
|
||
|
FILE *
|
||
|
OpenCheckFile( VOID );
|
||
|
|
||
|
BOOL
|
||
|
ComputeEntry(
|
||
|
FILE *CheckFile,
|
||
|
LPSTR FileName,
|
||
|
DWORD FileLength
|
||
|
);
|
||
|
|
||
|
DWORD
|
||
|
CheckSumFile(
|
||
|
FILE *InputHandle,
|
||
|
LPSTR PathName,
|
||
|
DWORD FileLength,
|
||
|
LPSTR FileName
|
||
|
);
|
||
|
|
||
|
BOOL fGenerateCheck = FALSE;
|
||
|
LPSTR RootOfTree = "C:\\NT";
|
||
|
BOOL fVerbose = FALSE;
|
||
|
BOOL fUsage = FALSE;
|
||
|
|
||
|
#ifndef COMPILED_FORDOS
|
||
|
int ThreadCount;
|
||
|
HANDLE ThreadListMutex;
|
||
|
HANDLE ThreadListSemaphore;
|
||
|
LIST_ENTRY WorkList;
|
||
|
|
||
|
#define ITEM_TYPE_EXIT 1
|
||
|
#define ITEM_TYPE_VALIDATE 2
|
||
|
#define ITEM_TYPE_GENERATE 3
|
||
|
|
||
|
typedef struct _WORK_ITEM {
|
||
|
LIST_ENTRY ItemLinks;
|
||
|
DWORD ItemType;
|
||
|
PVOID Base;
|
||
|
DWORD FileLength;
|
||
|
DWORD ActualSum;
|
||
|
char FileName[MAX_PATH];
|
||
|
} WORK_ITEM, *PWORK_ITEM;
|
||
|
|
||
|
|
||
|
PHANDLE ThreadHandles;
|
||
|
CRITICAL_SECTION GenerateCrit;
|
||
|
|
||
|
VOID
|
||
|
WriteCheckSumEntry(
|
||
|
FileName,
|
||
|
Sum,
|
||
|
FileLength
|
||
|
)
|
||
|
{
|
||
|
char lOutputLine[512];
|
||
|
int LineLength;
|
||
|
|
||
|
LineLength = sprintf(lOutputLine,"%s %x %x\n",FileName,Sum,FileLength);
|
||
|
if ( fVerbose ) {
|
||
|
fprintf(stdout,"Id %d %s",GetCurrentThreadId(),lOutputLine);
|
||
|
}
|
||
|
EnterCriticalSection(&GenerateCrit);
|
||
|
fwrite(lOutputLine,1,LineLength,GlobalCheckFile);
|
||
|
LeaveCriticalSection(&GenerateCrit);
|
||
|
}
|
||
|
|
||
|
|
||
|
DWORD
|
||
|
WorkerThread(
|
||
|
LPVOID WhoCares
|
||
|
)
|
||
|
{
|
||
|
HANDLE Objects[2];
|
||
|
PWORK_ITEM Item;
|
||
|
PLIST_ENTRY Entry;
|
||
|
int FilesProcessed = 0;
|
||
|
|
||
|
Objects[0] = ThreadListMutex;
|
||
|
Objects[1] = ThreadListSemaphore;
|
||
|
|
||
|
SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_ABOVE_NORMAL);
|
||
|
|
||
|
//
|
||
|
// Wait for and entry on the list, and exclusive ownership of the listhead
|
||
|
//
|
||
|
|
||
|
while(TRUE) {
|
||
|
WaitForMultipleObjects(2,Objects,TRUE,INFINITE);
|
||
|
|
||
|
|
||
|
Entry = RemoveHeadList(&WorkList);
|
||
|
Item = (PWORK_ITEM)(CONTAINING_RECORD(Entry,WORK_ITEM,ItemLinks));
|
||
|
|
||
|
ReleaseMutex(ThreadListMutex);
|
||
|
|
||
|
switch ( Item->ItemType ) {
|
||
|
case ITEM_TYPE_VALIDATE :
|
||
|
FilesProcessed++;
|
||
|
break;
|
||
|
|
||
|
case ITEM_TYPE_GENERATE :
|
||
|
FilesProcessed++;
|
||
|
{
|
||
|
DWORD Sum;
|
||
|
Sum = (DWORD)CheckSum(0,Item->Base,(Item->FileLength+1) >> 1);
|
||
|
UnmapViewOfFile(Item->Base);
|
||
|
WriteCheckSumEntry(Item->FileName,Sum,Item->FileLength);
|
||
|
break;
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
case ITEM_TYPE_EXIT :
|
||
|
default:
|
||
|
fprintf(stdout,"Id %d Processed %d Files\n",GetCurrentThreadId(),FilesProcessed);
|
||
|
ExitThread(1);
|
||
|
|
||
|
}
|
||
|
LocalFree(Item);
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
#endif
|
||
|
|
||
|
INT __cdecl
|
||
|
main( argc, argv )
|
||
|
int argc;
|
||
|
LPSTR argv[];
|
||
|
{
|
||
|
|
||
|
if (!ProcessParameters( argc, argv )) {
|
||
|
fUsage = TRUE;
|
||
|
}
|
||
|
|
||
|
if (fUsage) {
|
||
|
fprintf( stderr, "usage: checkrel [-?] display this message\n" );
|
||
|
fprintf( stderr, " [-r pathname] supply release root\n" );
|
||
|
fprintf( stderr, " [-v] verbose output\n" );
|
||
|
fprintf( stderr, " [-g] generate check file\n" );
|
||
|
fprintf( stderr, " [-t n] use n threads to process the data\n" );
|
||
|
}
|
||
|
else {
|
||
|
//
|
||
|
// if we are generating a check file, then generate it,
|
||
|
// otherwise just check the release
|
||
|
//
|
||
|
|
||
|
if ( fGenerateCheck ) {
|
||
|
GenerateCheckFile();
|
||
|
#ifndef COMPILED_FORDOS
|
||
|
if ( ThreadCount ) {
|
||
|
int i;
|
||
|
PWORK_ITEM Item;
|
||
|
for(i=0;i<ThreadCount;i++){
|
||
|
Item = LocalAlloc(LMEM_ZEROINIT,sizeof(*Item));
|
||
|
Item->ItemType = ITEM_TYPE_EXIT;
|
||
|
WaitForSingleObject(ThreadListMutex,INFINITE);
|
||
|
InsertTailList(&WorkList,&Item->ItemLinks);
|
||
|
ReleaseSemaphore(ThreadListSemaphore,1,NULL);
|
||
|
ReleaseMutex(ThreadListMutex);
|
||
|
}
|
||
|
WaitForMultipleObjects(ThreadCount,ThreadHandles,TRUE,INFINITE);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
}
|
||
|
else {
|
||
|
ValidateCheckFile();
|
||
|
}
|
||
|
}
|
||
|
return( 0 );
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
ProcessParameters(
|
||
|
int argc,
|
||
|
LPSTR argv[]
|
||
|
)
|
||
|
{
|
||
|
char c, *p;
|
||
|
BOOL Result;
|
||
|
char *WhoCares;
|
||
|
int i;
|
||
|
|
||
|
Result = TRUE;
|
||
|
while (--argc) {
|
||
|
p = *++argv;
|
||
|
if (*p == '/' || *p == '-') {
|
||
|
while (c = *++p)
|
||
|
switch (toupper( c )) {
|
||
|
case '?':
|
||
|
fUsage = TRUE;
|
||
|
break;
|
||
|
|
||
|
case 'R': {
|
||
|
|
||
|
argc--;
|
||
|
argv++;
|
||
|
|
||
|
RootOfTree = *argv;
|
||
|
GetFullPathName(RootOfTree,sizeof(RootBuffer),RootBuffer,&WhoCares);
|
||
|
RootOfTree = RootBuffer;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case 'G':
|
||
|
fGenerateCheck = TRUE;
|
||
|
break;
|
||
|
|
||
|
case 'V':
|
||
|
fVerbose = TRUE;
|
||
|
break;
|
||
|
|
||
|
#ifndef COMPILED_FORDOS
|
||
|
case 'T': {
|
||
|
DWORD ThreadId;
|
||
|
|
||
|
argc--;
|
||
|
argv++;
|
||
|
|
||
|
ThreadCount = atoi(*argv);
|
||
|
InitializeListHead(&WorkList);
|
||
|
ThreadListMutex = CreateMutex(NULL,FALSE,NULL);
|
||
|
ThreadListSemaphore = CreateSemaphore(NULL,0,0x70000000,NULL);
|
||
|
InitializeCriticalSection(&GenerateCrit);
|
||
|
if ( ThreadListMutex && ThreadListSemaphore ) {
|
||
|
ThreadHandles = LocalAlloc(LMEM_ZEROINIT,sizeof(HANDLE)*ThreadCount);
|
||
|
if ( ThreadHandles ) {
|
||
|
for(i=0;i<ThreadCount;i++) {
|
||
|
ThreadHandles[i] = CreateThread(
|
||
|
NULL,
|
||
|
0,
|
||
|
WorkerThread,
|
||
|
NULL,
|
||
|
0,
|
||
|
&ThreadId
|
||
|
);
|
||
|
if ( !ThreadHandles[i] ) {
|
||
|
ThreadCount = 0;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
ThreadCount = 0;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
ThreadCount = 0;
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
default:
|
||
|
fprintf( stderr, "checkrel: Invalid switch - /%c\n", c );
|
||
|
Result = FALSE;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return( Result );
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
WalkTree(
|
||
|
FILE *CheckFile,
|
||
|
LPSTR SubDir
|
||
|
)
|
||
|
{
|
||
|
char NextSubDir[MAX_PATH];
|
||
|
DWORD FindHandle;
|
||
|
char FindPattern[MAX_PATH];
|
||
|
char FindName[MAX_PATH];
|
||
|
DWORD FindSize;
|
||
|
BOOL b;
|
||
|
BOOL IsDir;
|
||
|
|
||
|
//
|
||
|
// recursively walk the system searching all files
|
||
|
//
|
||
|
|
||
|
//
|
||
|
// build the find pattern
|
||
|
//
|
||
|
|
||
|
strcpy(FindPattern,RootOfTree);
|
||
|
if ( SubDir ) {
|
||
|
strcat(FindPattern,"\\");
|
||
|
strcat(FindPattern,SubDir);
|
||
|
}
|
||
|
strcat(FindPattern,"\\*.*");
|
||
|
|
||
|
if ( fVerbose ) {
|
||
|
fprintf(stdout,"WalkTree %s \n",FindPattern);
|
||
|
}
|
||
|
|
||
|
FindHandle = PortFindFirstFile(FindPattern,FindName,&IsDir,&FindSize);
|
||
|
if ( FindHandle == -1 ) {
|
||
|
fprintf(stderr,"checkrel: FindFirst(%s) failed %d\n",FindPattern,errno);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
b = TRUE;
|
||
|
while(b) {
|
||
|
|
||
|
_strlwr(FindName);
|
||
|
|
||
|
//
|
||
|
// recurse if we are at a directory
|
||
|
//
|
||
|
|
||
|
if ( IsDir ) {
|
||
|
|
||
|
//
|
||
|
// if name is . or .., skip to findnext
|
||
|
//
|
||
|
|
||
|
if ( !strcmp(FindName,".") || !strcmp(FindName,"..") ) {
|
||
|
goto findnext;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// if name is w32x86 or w32mips, skip to findnext
|
||
|
//
|
||
|
|
||
|
if ( !strcmp(FindName,"w32mips") || !strcmp(FindName,"w32x86") ) {
|
||
|
goto findnext;
|
||
|
}
|
||
|
|
||
|
|
||
|
NextSubDir[0] = '\0';
|
||
|
if ( SubDir ) {
|
||
|
strcat(NextSubDir,SubDir);
|
||
|
strcat(NextSubDir,"\\");
|
||
|
}
|
||
|
strcat(NextSubDir,FindName);
|
||
|
WalkTree(CheckFile,NextSubDir);
|
||
|
}
|
||
|
else {
|
||
|
NextSubDir[0] = '\0';
|
||
|
if ( SubDir ) {
|
||
|
strcat(NextSubDir,SubDir);
|
||
|
strcat(NextSubDir,"\\");
|
||
|
}
|
||
|
strcat(NextSubDir,FindName);
|
||
|
b = ComputeEntry(CheckFile,NextSubDir,FindSize);
|
||
|
}
|
||
|
|
||
|
if ( !b ) {
|
||
|
fprintf(stderr,"checkrel: ComputeEntry faild\n");
|
||
|
return;
|
||
|
}
|
||
|
findnext:
|
||
|
b = PortFindNextFile(FindHandle,FindName,&IsDir,&FindSize);
|
||
|
}
|
||
|
PortFindClose(FindHandle);
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID
|
||
|
GenerateCheckFile( VOID )
|
||
|
{
|
||
|
FILE *CheckFile;
|
||
|
|
||
|
CheckFile = OpenCheckFile();
|
||
|
if ( !CheckFile ) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
WalkTree(CheckFile,NULL);
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
ValidateCheckFile( VOID )
|
||
|
{
|
||
|
FILE *CheckFile;
|
||
|
DWORD CheckSize, CheckSum;
|
||
|
char CheckName[MAX_PATH];
|
||
|
DWORD n;
|
||
|
LPSTR PathName;
|
||
|
FILE *FileHandle;
|
||
|
DWORD ActualSize;
|
||
|
DWORD ActualSum;
|
||
|
|
||
|
CheckFile = OpenCheckFile();
|
||
|
if ( !CheckFile ) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
PathName = malloc(strlen(RootOfTree)+MAX_PATH+1);
|
||
|
|
||
|
if ( !PathName ) {
|
||
|
fprintf(stderr,"checkrel: memory allocation for %d bytes failed\n",strlen(RootOfTree)+MAX_PATH+1);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
n = fscanf(CheckFile,"%s %x %x",CheckName,&CheckSum,&CheckSize);
|
||
|
while ( n != EOF ) {
|
||
|
if ( n != 3 ) {
|
||
|
fprintf(stderr,"checkrel: error in format\n");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Now form the file and do the checksum compare
|
||
|
//
|
||
|
|
||
|
strcpy(PathName,RootOfTree);
|
||
|
strcat(PathName,"\\");
|
||
|
strcat(PathName,CheckName);
|
||
|
|
||
|
FileHandle = fopen(PathName,"rb");
|
||
|
if ( !FileHandle ) {
|
||
|
fprintf(stderr,"checkrel: failed to open file %s %d\n",PathName,errno);
|
||
|
}
|
||
|
else {
|
||
|
ActualSize = _filelength(_fileno(FileHandle));
|
||
|
|
||
|
if ( ActualSize == 0xffffffff ) {
|
||
|
fprintf(stderr,"checkrel: unable to get file size for file %s %d\n",PathName,errno);
|
||
|
fclose(FileHandle);
|
||
|
}
|
||
|
else {
|
||
|
if ( ActualSize != CheckSize ) {
|
||
|
fprintf(stderr,"checkrel: FileSizes Differ for %s Actual %x vs. %x\n",PathName,ActualSize,CheckSize);
|
||
|
}
|
||
|
ActualSum = CheckSumFile(FileHandle,PathName,ActualSize,NULL);
|
||
|
if ( ActualSum ) {
|
||
|
if ( ActualSum != CheckSum ) {
|
||
|
fprintf(stderr,"checkrel: CheckSums Differ for %s Actual %x vs. %x\n",PathName,ActualSum,CheckSum);
|
||
|
}
|
||
|
}
|
||
|
if ( fVerbose ) {
|
||
|
fprintf(stdout,"%s Sum(%x vs %x) Size(%x vs %x)\n",PathName,ActualSum,CheckSum,ActualSize,CheckSize);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
n = fscanf(CheckFile,"%s %x %x",CheckName,&CheckSum,&CheckSize);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
FILE *
|
||
|
OpenCheckFile()
|
||
|
{
|
||
|
FILE *CheckFile;
|
||
|
|
||
|
GlobalCheckFile = (FILE *)-1;
|
||
|
CheckFileName = malloc(strlen(RootOfTree)+strlen(CHECK_NAME)+1);
|
||
|
if ( !CheckFileName ) {
|
||
|
return (FILE *)-1;
|
||
|
}
|
||
|
|
||
|
strcpy(CheckFileName,RootOfTree);
|
||
|
strcat(CheckFileName,CHECK_NAME);
|
||
|
|
||
|
if ( fVerbose ) {
|
||
|
fprintf(stdout,"checkrel: check name %s\n",CheckFileName);
|
||
|
}
|
||
|
|
||
|
CheckFile = fopen(CheckFileName,fGenerateCheck ? "wt" : "rt");
|
||
|
|
||
|
if ( !CheckFile ) {
|
||
|
fprintf(stderr,"checkrel: open %s failed %d\n",CheckFileName,errno);
|
||
|
}
|
||
|
GlobalCheckFile = CheckFile;
|
||
|
return CheckFile;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
ComputeEntry(
|
||
|
FILE *CheckFile,
|
||
|
LPSTR FileName,
|
||
|
DWORD FileLength
|
||
|
)
|
||
|
{
|
||
|
char PathName[MAX_PATH];
|
||
|
DWORD CheckSum;
|
||
|
DWORD LineLength;
|
||
|
|
||
|
strcpy(PathName,RootOfTree);
|
||
|
strcat(PathName,"\\");
|
||
|
strcat(PathName,FileName);
|
||
|
|
||
|
CheckSum = CheckSumFile(NULL,PathName,FileLength,FileName);
|
||
|
|
||
|
if ( CheckSum ) {
|
||
|
LineLength = sprintf(OutputLine,"%s %x %x\n",FileName,CheckSum,FileLength);
|
||
|
if ( fVerbose ) {
|
||
|
fprintf(stdout,"%s",OutputLine);
|
||
|
}
|
||
|
fwrite(OutputLine,1,LineLength,CheckFile);
|
||
|
}
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
DWORD
|
||
|
CheckSumFile(
|
||
|
FILE *InputHandle,
|
||
|
LPSTR PathName,
|
||
|
DWORD FileLength,
|
||
|
LPSTR FileName
|
||
|
)
|
||
|
|
||
|
{
|
||
|
|
||
|
FILE *FileHandle;
|
||
|
DWORD Sum;
|
||
|
signed char *pb;
|
||
|
LPDWORD pul;
|
||
|
PVOID Base;
|
||
|
DWORD cbread, cbreadtotal;
|
||
|
|
||
|
if ( InputHandle ){
|
||
|
FileHandle = InputHandle;
|
||
|
}
|
||
|
else {
|
||
|
FileHandle = fopen(PathName,"rb");
|
||
|
if ( !FileHandle ) {
|
||
|
fprintf(stderr,"checkrel: failed to open file %s %d\n",PathName,errno);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
#ifndef COMPILED_FORDOS
|
||
|
if ( ThreadCount ) {
|
||
|
PWORK_ITEM Item;
|
||
|
HANDLE Win32FileHandle;
|
||
|
HANDLE MappingHandle;
|
||
|
|
||
|
//
|
||
|
// Queue the generate request to a worker thread
|
||
|
//
|
||
|
|
||
|
Item = LocalAlloc(LMEM_ZEROINIT,sizeof(*Item));
|
||
|
|
||
|
if (!Item) {
|
||
|
goto bail;
|
||
|
}
|
||
|
Win32FileHandle = (HANDLE)_get_osfhandle(_fileno(FileHandle));
|
||
|
MappingHandle = CreateFileMapping(
|
||
|
Win32FileHandle,
|
||
|
NULL,
|
||
|
PAGE_READONLY,
|
||
|
0,
|
||
|
0,
|
||
|
NULL
|
||
|
);
|
||
|
if ( !MappingHandle ) {
|
||
|
fprintf(stderr,"checkrel: failed to map file %s %d\n",PathName,GetLastError());
|
||
|
fclose(FileHandle);
|
||
|
return 0;
|
||
|
}
|
||
|
Base = MapViewOfFile(
|
||
|
MappingHandle,
|
||
|
FILE_MAP_READ,
|
||
|
0,
|
||
|
0,
|
||
|
0
|
||
|
);
|
||
|
CloseHandle(MappingHandle);
|
||
|
if ( !Base ) {
|
||
|
fprintf(stderr,"checkrel: failed to map view of file %s %d\n",PathName,GetLastError());
|
||
|
fclose(FileHandle);
|
||
|
return 0;
|
||
|
}
|
||
|
fclose(FileHandle);
|
||
|
|
||
|
|
||
|
Item->ItemType = ITEM_TYPE_GENERATE;
|
||
|
Item->Base = Base;
|
||
|
Item->FileLength = FileLength;
|
||
|
strcpy(&Item->FileName[0],FileName);
|
||
|
WaitForSingleObject(ThreadListMutex,INFINITE);
|
||
|
InsertTailList(&WorkList,&Item->ItemLinks);
|
||
|
ReleaseSemaphore(ThreadListSemaphore,1,NULL);
|
||
|
ReleaseMutex(ThreadListMutex);
|
||
|
return 0;
|
||
|
}
|
||
|
bail:;
|
||
|
#endif
|
||
|
}
|
||
|
#ifdef COMPILED_FORDOS
|
||
|
Base = ReadBuffer;
|
||
|
|
||
|
//
|
||
|
// Read the file in large blocks and compute the checksum.
|
||
|
//
|
||
|
|
||
|
Sum = 0;
|
||
|
cbreadtotal = 0;
|
||
|
while (cbread = fread(ReadBuffer, 1, READ_BUFFER_SIZE, FileHandle)) {
|
||
|
cbreadtotal += cbread;
|
||
|
pb = Base;
|
||
|
|
||
|
//
|
||
|
// Make sure the last byte of the buffer is zero in case a
|
||
|
// partial buffer was read with an odd number of bytes in the
|
||
|
// buffer.
|
||
|
//
|
||
|
|
||
|
((PBYTE)ReadBuffer)[cbread] = 0;
|
||
|
|
||
|
//
|
||
|
// Compute the checksum using the same algorithm used for
|
||
|
// tcp/ip network packets. This is a word checksum with all
|
||
|
// carries folded back into the sum.
|
||
|
//
|
||
|
|
||
|
Sum = (DWORD)CheckSum(Sum, (LPWORD)ReadBuffer, (cbread + 1) >> 1);
|
||
|
}
|
||
|
#else
|
||
|
{
|
||
|
HANDLE Win32FileHandle;
|
||
|
HANDLE MappingHandle;
|
||
|
|
||
|
Win32FileHandle = (HANDLE)_get_osfhandle(_fileno(FileHandle));
|
||
|
MappingHandle = CreateFileMapping(
|
||
|
Win32FileHandle,
|
||
|
NULL,
|
||
|
PAGE_READONLY,
|
||
|
0,
|
||
|
0,
|
||
|
NULL
|
||
|
);
|
||
|
if ( !MappingHandle ) {
|
||
|
fprintf(stderr,"checkrel: failed to map file %s %d\n",PathName,GetLastError());
|
||
|
fclose(FileHandle);
|
||
|
return 0;
|
||
|
}
|
||
|
Base = MapViewOfFile(
|
||
|
MappingHandle,
|
||
|
FILE_MAP_READ,
|
||
|
0,
|
||
|
0,
|
||
|
0
|
||
|
);
|
||
|
CloseHandle(MappingHandle);
|
||
|
if ( !Base ) {
|
||
|
fprintf(stderr,"checkrel: failed to map view of file %s %d\n",PathName,GetLastError());
|
||
|
fclose(FileHandle);
|
||
|
return 0;
|
||
|
}
|
||
|
Sum = (DWORD)CheckSum(0,Base,(FileLength+1) >> 1);
|
||
|
UnmapViewOfFile(Base);
|
||
|
}
|
||
|
#endif
|
||
|
fclose(FileHandle);
|
||
|
|
||
|
if (Sum == 0) {
|
||
|
Sum = FileLength;
|
||
|
}
|
||
|
|
||
|
return(Sum);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
#ifndef COMPILED_FORDOS
|
||
|
DWORD
|
||
|
PortFindFirstFile(
|
||
|
LPSTR FindPattern,
|
||
|
LPSTR FindName,
|
||
|
LPBOOL IsDir,
|
||
|
LPDWORD FindSize
|
||
|
)
|
||
|
{
|
||
|
HANDLE FindHandle;
|
||
|
WIN32_FIND_DATA FindFileData;
|
||
|
|
||
|
FindHandle = FindFirstFile(FindPattern,&FindFileData);
|
||
|
if ( FindHandle != INVALID_HANDLE_VALUE ) {
|
||
|
strcpy(FindName,FindFileData.cFileName);
|
||
|
*FindSize = FindFileData.nFileSizeLow;
|
||
|
*IsDir = FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
|
||
|
}
|
||
|
return (DWORD)FindHandle;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
PortFindNextFile(
|
||
|
DWORD FindHandle,
|
||
|
LPSTR FindName,
|
||
|
LPBOOL IsDir,
|
||
|
LPDWORD FindSize
|
||
|
)
|
||
|
{
|
||
|
BOOL b;
|
||
|
WIN32_FIND_DATA FindFileData;
|
||
|
|
||
|
b = FindNextFile((HANDLE)FindHandle,&FindFileData);
|
||
|
if ( b ) {
|
||
|
strcpy(FindName,FindFileData.cFileName);
|
||
|
*FindSize = FindFileData.nFileSizeLow;
|
||
|
*IsDir = FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
|
||
|
}
|
||
|
return b;
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
PortFindClose(
|
||
|
DWORD FindHandle
|
||
|
)
|
||
|
{
|
||
|
FindClose((HANDLE)FindHandle);
|
||
|
}
|
||
|
#else
|
||
|
DWORD
|
||
|
PortFindFirstFile(
|
||
|
LPSTR FindPattern,
|
||
|
LPSTR FindName,
|
||
|
LPBOOL IsDir,
|
||
|
LPDWORD FindSize
|
||
|
)
|
||
|
{
|
||
|
struct find_t *FindHandle;
|
||
|
int error;
|
||
|
|
||
|
FindHandle = malloc(sizeof(*FindHandle));
|
||
|
|
||
|
error = _dos_findfirst(FindPattern,_A_RDONLY | _A_NORMAL | _A_DIR, FindHandle);
|
||
|
if ( error ) {
|
||
|
free(FindHandle);
|
||
|
return -1;
|
||
|
}
|
||
|
strcpy(FindName,FindHandle->name);
|
||
|
*FindSize = FindHandle->size;
|
||
|
*IsDir = FindHandle->attrib & 0x10;
|
||
|
return (DWORD)FindHandle;
|
||
|
}
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
PortFindNextFile(
|
||
|
DWORD FindHandle,
|
||
|
LPSTR FindName,
|
||
|
LPBOOL IsDir,
|
||
|
LPDWORD FindSize
|
||
|
)
|
||
|
{
|
||
|
BOOL b;
|
||
|
int error;
|
||
|
struct find_t *xxFindHandle;
|
||
|
|
||
|
xxFindHandle = (struct find_t *)FindHandle;
|
||
|
error = _dos_findnext( xxFindHandle );
|
||
|
if ( error ) {
|
||
|
return FALSE;
|
||
|
}
|
||
|
strcpy(FindName,xxFindHandle->name);
|
||
|
*FindSize = xxFindHandle->size;
|
||
|
*IsDir = FindHandle->attrib & 0x10;
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
VOID
|
||
|
PortFindClose(
|
||
|
DWORD FindHandle
|
||
|
)
|
||
|
{
|
||
|
free((int *)FindHandle);
|
||
|
}
|
||
|
|
||
|
WORD
|
||
|
CheckSum(
|
||
|
DWORD PartialSum,
|
||
|
LPWORD Source,
|
||
|
DWORD Length
|
||
|
)
|
||
|
|
||
|
{
|
||
|
|
||
|
register unsigned long t = PartialSum;
|
||
|
register unsigned long r;
|
||
|
|
||
|
while(Length--) {
|
||
|
t += *Source++;
|
||
|
}
|
||
|
|
||
|
while (r = (t & 0xFFFF0000) {
|
||
|
t &= 0x0000FFFF;
|
||
|
t += (r >> 16);
|
||
|
}
|
||
|
|
||
|
return t;
|
||
|
}
|
||
|
|
||
|
#endif
|