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

1854 lines
40 KiB
C

#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;
}