1854 lines
40 KiB
C
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;
|
||
|
}
|