|
|
#include "precomp.h"
#pragma hdrstop
/* File: search.c */ /**************************************************************************/ /* file search functions
/**************************************************************************/
extern PSTR LOCAL_SOURCE_DIRECTORY;
//*******************************************************************
//
// Exe Info
//
//*******************************************************************
typedef enum _EXETYPE { EXE_WIN16, EXE_WIN32, EXE_DOS, EXE_DUNNO } EXETYPE;
#define EXE_WIN16_SZ "WIN16"
#define EXE_WIN32_SZ "WIN32"
#define EXE_DOS_SZ "DOS"
#define EXE_DUNNO_SZ NULL
typedef struct _EXEINFO *PEXEINFO; typedef struct _EXEINFO { EXETYPE ExeType; SZ szExeType; SZ szDescr; } EXEINFO;
PEXEINFO ExeInfoAlloc( SZ szPath, SZ szFile );
BOOL FExeInfoInit( PEXEINFO pExeInfo, SZ szPath, SZ szFile );
BOOL FIsExeOrCom( SZ szFile );
BOOL FIsCom( SZ szFile );
BOOL FIsWin16( HANDLE Handle, PIMAGE_DOS_HEADER pDosHeader, PIMAGE_OS2_HEADER pOs2Header );
BOOL FFapi( HANDLE Handle, PIMAGE_OS2_HEADER pOs2Header, DWORD dwOffset );
SZ GetBaseName( SZ szFile );
SZ ReadWin16Descr( SZ szFile, HANDLE Handle, PIMAGE_DOS_HEADER pDosHeader, PIMAGE_OS2_HEADER pOs2Header );
SZ ReadWin32Descr( SZ szFile, HANDLE Handle, PIMAGE_DOS_HEADER pDosHeader, PIMAGE_NT_HEADERS pNtHeader );
SZ ReadDescr( HANDLE Handle, DWORD Offset, DWORD Size );
VOID ExeInfoFree( PEXEINFO pInfo );
#define ExeInfoGetType(p) ((p)->ExeType)
#define ExeInfoGetTypeSz(p) ((p)->szExeType)
#define ExeInfoGetDescr(p) ((p)->szDescr)
//
// Allocates an ExeInfo
//
PEXEINFO ExeInfoAlloc( SZ szPath, SZ szFile ) { PEXEINFO pExeInfo;
if (pExeInfo = (PEXEINFO)SAlloc( sizeof(EXEINFO) )) {
if ( !FExeInfoInit( pExeInfo, szPath, szFile ) ) { ExeInfoFree( pExeInfo ); pExeInfo = NULL; } }
return pExeInfo; }
//
// Initialize an ExeInfo
//
BOOL FExeInfoInit( PEXEINFO pExeInfo, SZ szPath, SZ szFile )
{
HANDLE Handle; BOOL fOkay = fFalse; IMAGE_DOS_HEADER DosHeader; IMAGE_OS2_HEADER Os2Header; IMAGE_NT_HEADERS NtHeader; DWORD BytesRead;
if ( !FIsExeOrCom(szFile) ) { pExeInfo->ExeType = EXE_DOS; pExeInfo->szExeType = EXE_DOS_SZ; pExeInfo->szDescr = GetBaseName( szFile ); return fTrue; }
//
// Initialize the pExeInfo so that it can be Freed up if something
// wrong happens.
//
pExeInfo->szDescr = NULL;
//
// Open file
//
Handle = CreateFile( szPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL );
if ( Handle != INVALID_HANDLE_VALUE ) {
//
// Read DOS header
//
if ( ReadFile( Handle, &DosHeader, sizeof(IMAGE_DOS_HEADER), &BytesRead, NULL ) && (BytesRead == sizeof(IMAGE_DOS_HEADER)) && (DosHeader.e_magic == IMAGE_DOS_SIGNATURE) ) {
//
// Read OS/2 header
//
if ( (SetFilePointer( Handle, DosHeader.e_lfanew, 0, FILE_BEGIN ) != -1) && ReadFile( Handle, &Os2Header, sizeof(IMAGE_OS2_HEADER), &BytesRead, NULL ) && (BytesRead == sizeof(IMAGE_OS2_HEADER)) && FIsWin16( Handle, &DosHeader, &Os2Header ) ) {
//
// WIN16 EXE
//
pExeInfo->ExeType = EXE_WIN16; pExeInfo->szExeType = EXE_WIN16_SZ; pExeInfo->szDescr = ReadWin16Descr( szFile, Handle, &DosHeader, &Os2Header ); fOkay = fTrue;
} else if ( (SetFilePointer( Handle, DosHeader.e_lfanew, 0, FILE_BEGIN ) != -1) && ReadFile( Handle, &NtHeader, sizeof(IMAGE_NT_HEADERS), &BytesRead, NULL ) && (BytesRead == sizeof(IMAGE_NT_HEADERS)) && (NtHeader.Signature == IMAGE_NT_SIGNATURE) ) {
//
// Make sure that it is a WIN32 subsystem exe
//
if ( (NtHeader.FileHeader.SizeOfOptionalHeader >= IMAGE_SIZEOF_NT_OPTIONAL_HEADER) && ((NtHeader.OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI) || (NtHeader.OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI)) ) {
//
// WIN32
//
pExeInfo->ExeType = EXE_WIN32; pExeInfo->szExeType = EXE_WIN32_SZ; // pExeInfo->szDescr = ReadWin32Descr( szFile, Handle, &DosHeader, &NtHeader );
pExeInfo->szDescr = GetBaseName( szFile ); fOkay = fTrue; }
} else {
//
// Assume DOS
//
pExeInfo->ExeType = EXE_DOS; pExeInfo->szExeType = EXE_DOS_SZ; pExeInfo->szDescr = GetBaseName( szFile ); fOkay = fTrue; } } else { //
// Might be a DOS .com file, which wouldn't have an exe header on it.
//
if ( FIsCom(szFile) ) { pExeInfo->ExeType = EXE_DOS; pExeInfo->szExeType = EXE_DOS_SZ; pExeInfo->szDescr = GetBaseName( szFile ); fOkay = fTrue; } }
CloseHandle( Handle );
if ( !fOkay ) {
pExeInfo->ExeType = EXE_DUNNO; pExeInfo->szExeType = EXE_DUNNO_SZ; pExeInfo->szDescr = NULL; fOkay = fTrue; } }
return fOkay; }
//
// Determines if the file is a Win16 app
//
BOOL FIsWin16( HANDLE Handle, PIMAGE_DOS_HEADER pDosHeader, PIMAGE_OS2_HEADER pOs2Header ) {
#define NE_TYPE(ne) (((BYTE *)(ne))[0x36])
BOOL fW16 = fFalse;
if ( pOs2Header->ne_magic == IMAGE_OS2_SIGNATURE ) {
switch ( NE_TYPE( pOs2Header ) ) {
case 0: // Unknown EXE type, may be a windows exe
//
// Assume this file is a Windows App iff:
// it has a "expected windows version" value or
// it test's FALSE as a FAPI app
//
if (pOs2Header->ne_expver != 0) {
fW16 = fTrue;
} else {
fW16 = !FFapi( Handle, pOs2Header, pDosHeader->e_lfanew ); } break;
case 2: // Windows EXE type
fW16 = fTrue; break;
default: // Definitly NOT a windows EXE (DOS4 or OS/2)
break; } }
return fW16; }
//
// Determine if the app is FAPI
//
BOOL FFapi( HANDLE Handle, PIMAGE_OS2_HEADER pOs2Header, DWORD dwOffset ) {
#define szDOSCALLS "DOSCALLS"
#define lenDOSCALLS 8
char buf[256]; char *pch; WORD UNALIGNED *pw; int n; int i; BOOL f = FALSE; DWORD BytesRead;
/*
* look through the imported module table for the name "DOSCALLS" if * found the EXE is a FAPI app. * * NOTE! assumes module table will fit in a 256 byte buffer */
// make sure this doesn't point off the end of the buffer we will use
if (pOs2Header->ne_modtab > sizeof(buf)) { return fFalse; }
SetFilePointer( Handle, dwOffset, 0, FILE_BEGIN ); ReadFile( Handle, buf, sizeof(buf), &BytesRead, NULL );
pw = (WORD UNALIGNED *)(buf + pOs2Header->ne_modtab);
for (i = 0; (unsigned)i < pOs2Header->ne_cmod; i++) { pch = buf + pOs2Header->ne_imptab + *pw++;
if (pch > (buf + sizeof(buf))) // be sure we don't go off the end
break;
n = (int)*pch++;
if (n == 0) break;
if ( (n == lenDOSCALLS) && !_strnicmp(szDOSCALLS,pch,lenDOSCALLS) ) { f = TRUE; break; } }
return f; }
//
// Obtains the base portion of a file name (i.e. no extension)
//
SZ GetBaseName( SZ szFile ) { SZ szEnd; SZ szLast; SZ sz; CB cbSize;
szEnd = szLast = szFile + strlen( szFile ) - 1;
//
// Look for last '.'
//
while ( (szEnd >= szFile) && (*szEnd != '.')) { szEnd--; }
if ( szEnd < szFile ) { cbSize = (CB)(szLast - szFile); } else { cbSize = (CB)(szEnd - szFile); }
if (sz = (SZ)SAlloc( cbSize+1 )) {
memcpy( sz, szFile, cbSize ); sz[cbSize] = '\0'; }
return sz; }
//
// Determines if a filename is COM
//
BOOL FIsCom( SZ szFile ) { SZ szEnd;
szEnd = szFile + strlen( szFile ) - 1;
//
// Look for last '.'
//
while ( (szEnd >= szFile) && (*szEnd != '.')) { szEnd--; }
if ( szEnd >= szFile ) { return (BOOL)( (CrcStringCompare( szEnd, ".COM" ) == crcEqual) );
}
return fFalse; }
//
// Determines if a filename is EXE or COM
//
BOOL FIsExeOrCom( SZ szFile ) { SZ szEnd;
szEnd = szFile + strlen( szFile ) - 1;
//
// Look for last '.'
//
while ( (szEnd >= szFile) && (*szEnd != '.')) { szEnd--; }
if ( szEnd >= szFile ) { return (BOOL)( (CrcStringCompare( szEnd, ".EXE" ) == crcEqual) || (CrcStringCompare( szEnd, ".COM" ) == crcEqual) );
}
return fFalse; }
//
// Gets a Win16 Description
//
SZ ReadWin16Descr( SZ szFile, HANDLE Handle, PIMAGE_DOS_HEADER pDosHeader, PIMAGE_OS2_HEADER pOs2Header ) { DWORD DescrOff; BYTE DescrSize; SZ szDescr = NULL; DWORD BytesRead;
UNREFERENCED_PARAMETER( pDosHeader );
//
// Try to get description (first entry in nonresident table).
//
DescrOff = pOs2Header->ne_nrestab;
if ( !(SetFilePointer( Handle, DescrOff, 0, FILE_BEGIN) != -1) || !ReadFile( Handle, &DescrSize, sizeof(BYTE), &BytesRead, NULL ) || !(BytesRead == sizeof(BYTE)) || !(szDescr = ReadDescr( Handle, DescrOff+1, (DWORD)DescrSize )) ) {
//
// Could not get description, try to get module name
// (first entry in resident table).
//
DescrOff = pOs2Header->ne_restab;
if ( !(SetFilePointer( Handle, DescrOff, 0, FILE_BEGIN) != -1) || !ReadFile( Handle, &DescrSize, sizeof(BYTE), &BytesRead, NULL ) || !(BytesRead == sizeof(BYTE)) || !(szDescr = ReadDescr( Handle, DescrOff+1, (DWORD)DescrSize )) ) {
//
// Could not get module name, use file base name.
//
szDescr = GetBaseName( szFile ); } }
return szDescr; }
#if 0
//
// Get Win32 Description
//
SZ ReadWin32Descr( SZ szFile, HANDLE Handle, PIMAGE_DOS_HEADER pDosHeader, PIMAGE_NT_HEADERS pNtHeader ) { DWORD DescrOff; DWORD DescrSize; SZ szDescr = NULL;
UNREFERENCED_PARAMETER( pDosHeader ); //
// Try to get the description
//
DescrOff = pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COPYRIGHT].VirtualAddress; DescrSize = pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COPYRIGHT].Size;
if ( !(szDescr = ReadDescr( Handle, DescrOff, DescrSize ) ) ) {
//
// Could not get description, try to get module name.
//
// BUGBUG: Where do we find the module name?
//
//
// Could not get module name, use file base name.
//
szDescr = GetBaseName( szFile ); }
return szDescr; } #endif
//
// Reads a module description
//
SZ ReadDescr( HANDLE Handle, DWORD Offset, DWORD Size )
{ SZ szDescr = NULL; DWORD BytesRead; size_t SizeUsed; SZ sz;
if ( Size > 0 ) {
if (szDescr = (SZ)SAlloc( Size+1 )) {
//
// Read description
//
if ( (SetFilePointer( Handle, Offset, 0, FILE_BEGIN) != -1) && ReadFile( Handle, szDescr, Size, &BytesRead, NULL) && (BytesRead == Size) ) {
//
// Get rid of padding blanks
//
sz = szDescr+Size-1;
while ( (sz >= szDescr) && ( (*sz == ' ') || (*sz == '\t') ) ) { sz--; }
sz++; sz = '\0'; SizeUsed = (size_t)(sz-szDescr);
//
// If description has quotes or commas, or if it is longer
// than 26 characters, we don't want it.
//
if ( (SizeUsed > 25) || (strcspn( szDescr, """," ) >= SizeUsed) ) {
SFree(szDescr); szDescr = NULL;
} else {
if ( (SizeUsed < Size) && (szDescr = SRealloc( szDescr, SizeUsed))) {
*(szDescr+SizeUsed) = '\0'; } }
} else {
SFree(szDescr); szDescr = NULL; } } }
return szDescr; }
//
// Frees an Exe info
//
VOID ExeInfoFree( PEXEINFO pInfo ) { if ( pInfo->szDescr ) { SFree(pInfo->szDescr); } SFree(pInfo); }
//*******************************************************************
//
// File List
//
//*******************************************************************
typedef struct _FILELIST *PFILELIST; typedef struct _FILELIST { SYMTAB SymTab; } FILELIST;
PFILELIST FileListAlloc( SZ szFiles );
BOOL FFileListInit( PFILELIST pFileList );
VOID FileListFree( PFILELIST pFileList );
VOID FileListDealloc( PFILELIST pFileList );
BOOL FFileInFileList( SZ szFileName, PFILELIST pFileList );
BOOL FFileListAdd( SZ szFileName, PFILELIST pFileList );
//
// Allocates a file list
//
PFILELIST FileListAlloc( SZ szFiles ) { BOOL fOkay = fFalse; RGSZ rgszFile; PFILELIST pFileList = NULL; INT iFile;
if (rgszFile = RgszFromSzListValue( szFiles )) {
if (pFileList = (PFILELIST)SAlloc( sizeof(FILELIST) )) {
FFileListInit( pFileList );
fOkay = fTrue;
if ( rgszFile[0] ) {
//
// Add files to FileList.
//
for ( iFile = 0; fOkay && rgszFile[iFile]; iFile++ ) {
if ( !(fOkay = FFileListAdd( rgszFile[iFile], pFileList ))) {
FileListFree( pFileList ); pFileList = NULL; } } } }
FFreeRgsz( rgszFile ); }
return pFileList; }
//
// Initializes a File list
//
BOOL FFileListInit( PFILELIST pFileList ) { USHORT iHashBucket;
for (iHashBucket = 0; iHashBucket < cHashBuckets; iHashBucket++) { pFileList->SymTab.HashBucket[iHashBucket] = NULL; }
return fTrue; }
//
// Frees a file list
//
VOID FileListFree( PFILELIST pFileList ) { FileListDealloc( pFileList ); SFree(pFileList); }
//
// Deallocates a file list
//
VOID FileListDealloc ( PFILELIST pFileList ) { USHORT iHashBucket;
for (iHashBucket = 0; iHashBucket < cHashBuckets; iHashBucket++) {
PSTE pste = pFileList->SymTab.HashBucket[iHashBucket];
while (pste != (PSTE)NULL) {
PSTE psteSav = pste->psteNext;
FFreePste(pste); pste = psteSav; } } }
//
// Finds a file in a file list
//
BOOL FFileInFileList( SZ szFileName, PFILELIST pFileList ) { PPSTE ppste; PSYMTAB pSymTab = &(pFileList->SymTab);
if ( szFileName && (szFileName[0] != '\0') ) {
ppste = PpsteFindSymbol( pSymTab, szFileName );
AssertRet(ppste != (PPSTE)NULL, fFalse);
if (*ppste == (PSTE)NULL) { return fFalse; }
AssertRet( (*ppste)->szSymbol != (SZ)NULL && *((*ppste)->szSymbol) != '\0' && (*ppste)->szValue != (SZ)NULL, fFalse);
if (CrcStringCompare(szFileName, (*ppste)->szSymbol) != crcEqual) { return fFalse; }
return fTrue; }
return fFalse; }
//
// Adds a file to the file list
//
BOOL FFileListAdd( SZ szFileData, PFILELIST pFileList ) {
BOOL fOkay = fFalse; PPSTE ppste; SZ szFile; SZ szValue; PSYMTAB pSymTab = &(pFileList->SymTab);
if ( szFileData ) {
if ( (szFile = SzDupl(szFileData)) != NULL ) {
SzStrUpper( szFile );
if ( (szValue = SzDupl("")) != NULL ) {
fOkay = fTrue;
} else {
SFree(szFile); } } }
if ( fOkay ) {
ppste = PpsteFindSymbol( pSymTab, szFile );
if ( *ppste != NULL && CrcStringCompare( (*ppste)->szSymbol, szFile) == crcEqual) {
if ((*ppste)->szValue == NULL) {
SFree(szFile); SFree(szValue); fOkay = fFalse; goto AddExit; }
SFree((*ppste)->szValue); SFree(szFile);
(*ppste)->szValue = NULL;
} else {
PSTE pste;
if ( (pste = PsteAlloc()) == NULL ) {
SFree(szFile); SFree(szValue); fOkay = fFalse; goto AddExit; }
pste->szSymbol = szFile;
#ifdef SYMTAB_STATS
pSymTab->BucketCount[UsHashFunction(szFile)]++; #endif
pste->szValue = NULL; pste->psteNext = *ppste; *ppste = pste; }
(*ppste)->szValue = szValue;
}
AddExit:
return fOkay; }
//*******************************************************************
//
// Search List
//
//*******************************************************************
typedef struct _SEARCHLIST *PSEARCHLIST; typedef struct _SEARCHLIST { DWORD dwPatterns; RGSZ rgszPattern; FILELIST FileList; } SEARCHLIST;
PSEARCHLIST SearchListAlloc( SZ szFiles );
VOID SearchListFree( PSEARCHLIST pList );
BOOL FSearchListAddPattern( SZ szPattern, PSEARCHLIST pSearchList );
BOOL FFileInSearchList( SZ szFileName, PSEARCHLIST pSearchList );
BOOL FHasWildCard( SZ szFile );
BOOL FPatternMatch( SZ szFile, SZ szPattern );
//
// Allocates a search list
//
PSEARCHLIST SearchListAlloc( SZ szFiles ) { BOOL fOkay = fTrue; RGSZ rgszFile; PSEARCHLIST pSearchList = NULL; INT iFile;
if (rgszFile = RgszFromSzListValue( szFiles )) {
if ( rgszFile[0] != NULL ) {
if (pSearchList = (PSEARCHLIST)SAlloc( sizeof(SEARCHLIST) )) {
FFileListInit( &(pSearchList->FileList) );
if ( pSearchList->rgszPattern = (RGSZ)SAlloc( sizeof(SZ) ) ) {
pSearchList->rgszPattern[0] = NULL; pSearchList->dwPatterns = 0;
//
// Add files to FileList.
//
for ( iFile = 0; fOkay && rgszFile[iFile]; iFile++ ) {
//
// If the file has wildcards, add it to the pattern list,
// otherwise add it to the file list
//
if ( FHasWildCard( rgszFile[iFile] ) ) {
fOkay = FSearchListAddPattern( rgszFile[iFile], pSearchList );
} else {
fOkay = FFileListAdd( rgszFile[iFile], &(pSearchList->FileList) );
}
if (!fOkay) {
SearchListFree( pSearchList ); pSearchList = NULL; } }
} else {
SFree(pSearchList); pSearchList = NULL; } } }
FFreeRgsz( rgszFile ); }
return pSearchList; }
//
// Frees a search list
//
VOID SearchListFree( PSEARCHLIST pSearchList ) { FileListDealloc( &(pSearchList->FileList) ); FFreeRgsz( pSearchList->rgszPattern ); SFree(pSearchList); }
//
// Adds a pattern to the search list
//
BOOL FSearchListAddPattern( SZ szPattern, PSEARCHLIST pSearchList ) { SZ sz; RGSZ rgsz; BOOL fOkay = fFalse;
if (sz = SzDupl( szPattern )) {
rgsz = (RGSZ)SRealloc( pSearchList->rgszPattern, ((pSearchList->dwPatterns+2)*sizeof(SZ)));
if ( rgsz ) {
rgsz[pSearchList->dwPatterns] = sz; rgsz[pSearchList->dwPatterns+1] = NULL;
pSearchList->rgszPattern = rgsz; pSearchList->dwPatterns++;
fOkay = fTrue;
} else {
SFree(sz); } }
return fOkay; }
//
// Determines if a file name is in the search list
//
BOOL FFileInSearchList( SZ szFileName, PSEARCHLIST pSearchList ) { INT i;
if ( FFileInFileList( szFileName, &(pSearchList->FileList) ) ) { return fTrue; } else {
for (i=0; pSearchList->rgszPattern[i]; i++ ) {
if ( FPatternMatch( szFileName, pSearchList->rgszPattern[i] ) ) { return fTrue; } } }
return fFalse; }
//
// Determines if a file name has a wildcard
//
BOOL FHasWildCard( SZ szFile ) { return (strcspn( szFile, "*?" ) < strlen( szFile ) ); }
BOOL FPatternMatch( SZ szFile, SZ szPattern ) { switch (*szPattern) { case '\0': return ( *szFile == '\0' ); case '?': return ( *szFile != '\0' && FPatternMatch (szPattern + 1, szFile + 1) ); case '*': do { if (FPatternMatch (szPattern + 1, szFile)) return fTrue; } while (*szFile++); return fFalse; default: return ( toupper (*szFile) == toupper (*szPattern) && FPatternMatch (szPattern + 1, szFile + 1) ); } }
//*******************************************************************
//
// Found List
//
//*******************************************************************
#define FOUNDLIST_INCR 32
typedef struct _FOUNDLIST *PFOUNDLIST; typedef struct _FOUNDLIST { DWORD Index; DWORD Size; RGSZ rgszList; } FOUNDLIST;
PFOUNDLIST FoundListAlloc( );
VOID FoundListFree( PFOUNDLIST pList );
BOOL FoundListAdd( SZ szFile, SZ szDirectory, PEXEINFO pExeInfo, PFOUNDLIST pFoundList );
SZ SzFromFoundList( PFOUNDLIST pFoundList );
//
// Initialize a Found List
//
PFOUNDLIST FoundListAlloc( ) { PFOUNDLIST pFoundList;
if ( (pFoundList = (PFOUNDLIST)SAlloc( sizeof(FOUNDLIST) )) != NULL ) {
if ( (pFoundList->rgszList = (RGSZ)SAlloc( FOUNDLIST_INCR * sizeof(SZ) )) != NULL ) {
pFoundList->Index = 0; pFoundList->Size = FOUNDLIST_INCR; pFoundList->rgszList[0] = NULL;
} else {
SFree(pFoundList); pFoundList = (PFOUNDLIST)NULL; } }
return pFoundList; }
//
// Free a found list
//
VOID FoundListFree( PFOUNDLIST pFoundList ) { RGSZ rgszList;
rgszList = (RGSZ)SRealloc( pFoundList->rgszList, ((pFoundList->Index+1)*sizeof(SZ)));
FFreeRgsz( rgszList ); SFree(pFoundList); }
//
// Add and entry to the found list
//
BOOL FoundListAdd ( SZ szFile, SZ szDirectory, PEXEINFO pExeInfo, PFOUNDLIST pFoundList ) { BOOL fOkay = fFalse; RGSZ rgszEntry; RGSZ rgszList; SZ szEntry;
if (rgszEntry = (RGSZ)SAlloc( 5 * sizeof(SZ) )) {
rgszEntry[0] = szFile; rgszEntry[1] = szDirectory; rgszEntry[2] = ExeInfoGetTypeSz( pExeInfo ); rgszEntry[3] = ExeInfoGetDescr( pExeInfo ); rgszEntry[4] = NULL;
if (szEntry = SzListValueFromRgsz( rgszEntry )) {
if ( pFoundList->Index >= (pFoundList->Size - 1) ) {
rgszList = (RGSZ)SRealloc( pFoundList->rgszList, ((pFoundList->Size+FOUNDLIST_INCR)*sizeof(SZ)));
if ( rgszList ) {
pFoundList->Size += FOUNDLIST_INCR; pFoundList->rgszList = rgszList; fOkay = fTrue; }
} else {
fOkay = fTrue; }
if ( fOkay ) {
pFoundList->rgszList[pFoundList->Index++] = szEntry; pFoundList->rgszList[pFoundList->Index] = NULL;
} else {
SFree(szEntry); } }
SFree(rgszEntry);
}
return fOkay; }
//
// Get SZ from found list
//
SZ SzFromFoundList( PFOUNDLIST pFoundList ) { return SzListValueFromRgsz( pFoundList->rgszList ); }
//*******************************************************************
//
// Application Search
//
//*******************************************************************
extern HWND hwndFrame;
CHAR GaugeText1[50]; CHAR GaugeText2[50]; CHAR GaugeText3[50];
WIN32_FIND_DATA FindData; #define BARRANGE 30000
//
// Local Prototypes
//
BOOL APIENTRY FSearchDirectoryList( RGSZ rgszDirs, BOOL fRecurse, BOOL fSilent, PSEARCHLIST pSearchList, PFILELIST pWin16Restr, PFILELIST pWin32Restr, PFILELIST pDosRestr, PFOUNDLIST pFoundList );
BOOL APIENTRY FSearchDirectory( SZ szDirectory, BOOL fRecurse, BOOL fSilent, PSEARCHLIST pSearchList, PFILELIST pWin16Restr, PFILELIST pWin32Restr, PFILELIST pDosRestr, PFOUNDLIST pFoundList, INT Position, INT Range, SZ szDisplayBuffer );
//
// Purpose:
//
// Prepares for application search.
//
// Arguments:
//
// szInfVar - Where to put the result
// szDirList - List of directories to search
// fRecurse - Recursive flag
// fSilent - Silent mode flag
// szSearchList - List of files to search, can have wildcards
// szWin16Restr - Win16 restriction list
// szWin32Restr - Win32 restriction list
// szDosRestr - Dos restriction list
//
// Returns:
//
// fTrue if success.
//
BOOL APIENTRY FSearchDirList( SZ szInfVar, SZ szDirList, BOOL fRecurse, BOOL fSilent, SZ szSearchList, SZ szWin16Restr, SZ szWin32Restr, SZ szDosRestr ) { BOOL fOkay = fFalse; RGSZ rgszDirs; PSEARCHLIST pSearchList; PFILELIST pWin16Restr; PFILELIST pWin32Restr; PFILELIST pDosRestr; PFOUNDLIST pFoundList; SZ szResult;
SetCursor(CurrentCursor = LoadCursor(NULL,IDC_WAIT)); fSilent = (fSilent || fSilentSystem);
if ( rgszDirs = RgszFromSzListValue( szDirList ) ) {
if ( pSearchList = SearchListAlloc( szSearchList )) {
if ( pWin16Restr = FileListAlloc( szWin16Restr ) ) {
if ( pWin32Restr = FileListAlloc( szWin32Restr ) ) {
if ( pDosRestr = FileListAlloc( szDosRestr ) ) {
if ( pFoundList = FoundListAlloc() ) {
SetCursor(CurrentCursor = LoadCursor(NULL,IDC_ARROW)); fOkay = FSearchDirectoryList( rgszDirs, fRecurse, fSilent, pSearchList, pWin16Restr, pWin32Restr, pDosRestr, pFoundList );
if ( fOkay ) {
if ( szResult = SzFromFoundList( pFoundList ) ) {
while (!FAddSymbolValueToSymTab( szInfVar, szResult)) {
if (!FHandleOOM(hwndFrame)) {
fOkay = fFalse; break;
} }
SFree(szResult);
} else {
fOkay = fFalse; } }
FoundListFree( pFoundList ); }
FileListFree( pDosRestr ); }
FileListFree( pWin32Restr ); }
FileListFree( pWin16Restr ); }
SearchListFree( pSearchList ); }
FFreeRgsz( rgszDirs ); }
return fOkay; }
//
// Purpose:
//
// Performs the application search.
//
// Arguments:
//
// rgszDirs - List of directories to traverse
// fRecurse - Recursive flag
// fSilent - Silent mode flag
// pSearchList - The list of files to search
// pWin16Restr - List of Win16 restrictions
// pWin32Restr - List of Win32 restrictions
// pDosRestr - List of DOS restrictions
// pFoundList - Found list
//
// Returns:
//
// fTrue if success.
//
BOOL APIENTRY FSearchDirectoryList( RGSZ rgszDirs, BOOL fRecurse, BOOL fSilent, PSEARCHLIST pSearchList, PFILELIST pWin16Restr, PFILELIST pWin32Restr, PFILELIST pDosRestr, PFOUNDLIST pFoundList ) {
DWORD iDir; DWORD cDirs; INT SubRange; INT Pos; CHAR szDirectory[ cchlFullPathMax ]; CHAR szDisplayBuffer[cchlFullPathMax ]; BOOL fOkay = fTrue;
//
// Figure out how many directories we have to traverse
//
for ( cDirs = 0, iDir = 0; rgszDirs[iDir] != NULL; iDir++ ) { if ( *rgszDirs[iDir] != '\0' ) { cDirs++; } }
//
// Traverse the directories
//
if ( cDirs > 0 ) {
if (!fSilent) {
SZ szText;
ProOpen(hwndFrame, 0); ProSetBarRange(BARRANGE); ProSetBarPos(0);
szText = SzFindSymbolValueInSymTab("ProText1"); if (szText) { strcpy(GaugeText1, szText); }
szText = SzFindSymbolValueInSymTab("ProText2"); if (szText) { strcpy(GaugeText2, szText); }
szText = SzFindSymbolValueInSymTab("ProText3"); if (szText) { strcpy(GaugeText3, szText); }
ProSetText(ID_STATUS1, GaugeText1); ProSetText(ID_STATUS4, ""); }
SubRange = BARRANGE/cDirs; Pos = 0;
//
// Do one directory at a time
//
for ( iDir = 0; fOkay && FYield() && !fUserQuit && (iDir < cDirs); iDir++ ) {
SZ szEnd; BOOL fRecursive;
strcpy( szDirectory, rgszDirs[iDir] ); szEnd = szDirectory + strlen( szDirectory ) - 1;
if ( ( (szEnd - szDirectory) >= 1) && ( szDirectory[1] == ':' ) && ( szDirectory[2] == '\0' ) ) {
fRecursive = fTrue;
} else {
fRecursive = fRecurse; }
if ( *szEnd == '\\' ) { *szEnd = '\0'; }
fOkay = FSearchDirectory( szDirectory, fRecursive, fSilent, pSearchList, pWin16Restr, pWin32Restr, pDosRestr, pFoundList, Pos, SubRange, szDisplayBuffer );
Pos += SubRange; }
if (!fSilent) { ProSetBarPos(BARRANGE - 1); ProClose(hwndFrame); } }
return fOkay; }
//
// Purpose:
//
// Performs the application search in one directory
//
// Arguments:
//
// szDirectory - Directory to traverse
// fRecurse - Recursive flag
// fSilent - Silent mode flag
// pSearchList - The list of files to search
// pWin16Restr - List of Win16 restrictions
// pWin32Restr - List of Win32 restrictions
// pDosRestr - List of DOS restrictions
// pFoundList - Found list
// Position - Gauge initial position
// Range - Gauge range
// szDisplayBuffer - Tmp buffer.
//
// Returns:
//
// fTrue if success.
//
BOOL APIENTRY FSearchDirectory( SZ szDirectory, BOOL fRecurse, BOOL fSilent, PSEARCHLIST pSearchList, PFILELIST pWin16Restr, PFILELIST pWin32Restr, PFILELIST pDosRestr, PFOUNDLIST pFoundList, INT Position, INT Range, SZ szDisplayBuffer ) {
SZ pFileName; HANDLE FindHandle; BOOL fOkay = fTrue; INT cDirectories = 0; INT SubRange; INT Pos; PEXEINFO pExeInfo; BOOL fAdd;
if ( !szDirectory || szDirectory[0] == '\0' || szDirectory[0] == '.') { return fFalse; }
//
// catch local source directory -- don't want to find files in there!
//
if(!_strnicmp(szDirectory+2,LOCAL_SOURCE_DIRECTORY,lstrlen(LOCAL_SOURCE_DIRECTORY))) { return fTrue; }
if (!fSilent) { wsprintf(szDisplayBuffer, "%s%s", GaugeText2, szDirectory ); ProSetText(ID_STATUS2, szDisplayBuffer); }
pFileName = szDirectory + strlen( szDirectory ); SzStrCat( szDirectory, "\\*.*" );
FindHandle = FindFirstFile( szDirectory, &FindData );
if ( FindHandle != INVALID_HANDLE_VALUE ) {
//
// Look at all files under this directory.
//
do { if ( FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {
//
// Increment the count of directories just in case we're interactive
// and we want to recurse.
//
if ( FindData.cFileName[0] != '.' ) { cDirectories++; }
} else {
//
// If the file is in the search list, determine if we have to add it
// to the found list and if so add it.
//
SzStrUpper( FindData.cFileName );
if ( FFileInSearchList( FindData.cFileName, pSearchList ) ) {
*pFileName = '\0'; SzStrCat( szDirectory, "\\" ); SzStrCat( szDirectory, FindData.cFileName ); if ( ((pExeInfo = ExeInfoAlloc( szDirectory, FindData.cFileName )) != NULL) ) {
switch( ExeInfoGetType( pExeInfo ) ) {
case EXE_WIN16: //
// We only add if not in Win16Restr
//
fAdd = !FFileInFileList( FindData.cFileName, pWin16Restr ); break;
case EXE_WIN32: //
// We only add if not in Win32Restr
//
fAdd = !FFileInFileList( FindData.cFileName, pWin32Restr ); break;
case EXE_DOS: //
// We only add if in DosRestr
//
fAdd = FFileInFileList( FindData.cFileName, pDosRestr ); break;
default: fAdd = fFalse; break; }
if ( fAdd ) {
if (!fSilent) { wsprintf(szDisplayBuffer, "%s%s", GaugeText3, FindData.cFileName ); ProSetText(ID_STATUS3, szDisplayBuffer); }
*pFileName = '\\'; *(pFileName+1) = '\0'; fOkay = FoundListAdd( FindData.cFileName, szDirectory, pExeInfo, pFoundList ); }
ExeInfoFree( pExeInfo ); } } }
} while ( fOkay && FYield() && !fUserQuit && FindNextFile( FindHandle, &FindData ));
FindClose( FindHandle );
//
// Recurse thru all the subdirectories if the fRecurse flag is set.
//
if ( fOkay && fRecurse && !fUserQuit && (cDirectories > 0) ) {
*pFileName = '\0'; SzStrCat( szDirectory, "\\*.*" );
FindHandle = FindFirstFile( szDirectory, &FindData );
if ( FindHandle != INVALID_HANDLE_VALUE ) {
SubRange = Range/cDirectories; Pos = Position;
do {
if ( (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && (FindData.cFileName[0] != '.') ) {
*pFileName = '\\'; *(pFileName+1) = '\0'; SzStrCat( szDirectory, FindData.cFileName );
fOkay = FSearchDirectory( szDirectory, fRecurse, fSilent, pSearchList, pWin16Restr, pWin32Restr, pDosRestr, pFoundList, Pos, SubRange, szDisplayBuffer );
Pos += SubRange;
}
} while ( fOkay && FYield() && !fUserQuit && FindNextFile( FindHandle, &FindData ));
FindClose( FindHandle ); } } }
if ( !fSilent && (Range > 0) ) { ProSetBarPos( Position + Range - 1 ); }
//
// Restore original Directory name.
//
*pFileName = '\0';
return fOkay; }
|