Got a bit of a conceptual question here. I have a piece of code that
performs a recursive search of the users hard disk and generates a list of
files. Nothing new here. My code is based around the FindFirstFile /
FindNextFile API's. From what I can see, there doesn't seem to be a way to
specify a wildcard search mask i.e. *.exe so it seems necessary to check for
.exe extension within the search, which I do like this:
AnsiString sFile = (AnsiString)fdFindFileData.cFileName;
if (ExtractFileExt(sFile).AnsiCompareIC(".exe")== 0)
// add to my list
- using ExtractFileExt() to retrieve the file extension. This seemed to
work fine. When I run it on my development machine, I get 2982 files
returned. However, if I fire up a command prompt and do dir *.exe /s I get
3001 files returned, a difference of 19 files. I dumped both lists to text
files and compared them (which I had to do by hand because they weren't in
the same order and I couldn't be bothered to write something to do it :-) ).
In the dir *.exe dump, I have some file like this:
C:\WINDOWS\Installer\$PatchCache$\Managed\9040110900063D11C8EF10054038389C\11.0.5614\SCANOST.EXE_1033
when I examine the properties, they appear as executable files (although
they appear to be back-ups and are not executable). Based on this, I was
wondering what the best option is to truly determine a executable?
My first thoughts are to just ignore them as they are not executable
per-say, but i'm interested in how the dir commend determines there file
type. Simply looking for ".exe" in the file name would not work because it
is possible to have a text document with the name "textfile.exe.txt".
Any thoughts or suggestions
Mike
> My code is based around the FindFirstFile / FindNextFile API's. From what
> I can see, there doesn't seem to be a way to specify a
> wildcard search mask i.e. *.exe
Yes, there is:
HANDLE hFile = FindFirstFile("*.exe", &fdFindFileData);
To do it recursively, however, you would need two separate searches - *.exe
to find just files in a single folder, and then *.* to find subfolders for
recursion. It is easier to just use *.* by itself and then filter the
results as needed.
> But it does not work for recursive searches.
Sure, it does:
void __fastcall ScanForApps(const AnsiString &Folder, TStrings *Matches)
{
AnsiString tmpFolder = IncludeTrailingBackslash(Folder);
WIN32_FIND_DATA fd = {0};
HANDLE hFile = FindFirstFile( (tmpFolder + "*.*").c_str(), &fd);
if( hFile != INVALID_HANDLE_ VALUE )
{
do
{
if( fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
ScanForApps(tmpFolder + fd.cFileName, Matches);
else if( AnsiSameText(ExtractFileExt(fd.cFileName),
".exe") )
Matches->Add(tmpFolder + fd.cFileName);
}
while( FindNextFile(hFile, &fd) );
FindClose(hFile);
}
}
> when I examine the properties, they appear as executable files (although
> they appear to be back-ups and are not executable). Based on this, I
> was wondering what the best option is to truly determine a executable?
Open each file and analyze its contents to see if a PE (Portable Executable)
header is present.
> My first thoughts are to just ignore them as they are not executable
> per-say, but i'm interested in how the dir commend determines there
> file type.
It looks at the file attributes, which you are not doing yet.
> Simply looking for ".exe" in the file name would not work because
> it is possible to have a text document with the name "textfile.exe.txt".
The extension on such a file is ".txt", not ".exe" or ".exe.txt". A file's
extension begins at the last "." in the name.
Gambit
>Got a bit of a conceptual question here. I have a piece of code that
>performs a recursive search of the users hard disk and generates a list of
>files. Nothing new here. My code is based around the FindFirstFile /
>FindNextFile API's. From what I can see, there doesn't seem to be a way to
>specify a wildcard search mask i.e. *.exe so it seems necessary to check for
>.exe extension within the search, which I do like this:
I use "*.exe" just fine.
What problem are you having with it?
This bit from one of my apps:
* do all files for this directory */
void AddNewFiles(const char*Directory,const char* ext)
{ HANDLE ff;
WIN32_FIND_DATA fblk;
char filename[MAXPATH];
sprintf(filename,"%s*.%s",Directory,ext);
ff=FindFirstFile(filename,&fblk);
>C:\WINDOWS\Installer\$PatchCache$\Managed\9040110900063D11C8EF10054038389C\11.0.5614\SCANOST.EXE_1033
>
>when I examine the properties, they appear as executable files (although
>they appear to be back-ups and are not executable). Based on this, I was
>wondering what the best option is to truly determine a executable?
>
>My first thoughts are to just ignore them as they are not executable
>per-say, but i'm interested in how the dir commend determines there file
>type. Simply looking for ".exe" in the file name would not work because it
>is possible to have a text document with the name "textfile.exe.txt".
The file type is the *last-dotted-item*
So your example is still type .txt, even with .exe embeded.
More relevant would be if you thought data.hexed was an exe.
I think if you used "*.exe" in your FFF, you would also be
presented with .EXE_1033, but your current code is more
stringent with it's AnsiCompareIC(".exe") rejecting it.
bool WINAPI IsExeName(const WIN32_FIND_DATA & wfd)
{
const char *exten = strrchr(wfd.cFileName, '.');
return (exten != NULL) && !stricmp(exten, ".ext");
}
:
:
if (IsExeName(fdFindFileData))
// add to my list
. Ed
> Mike Collins wrote in message
> news:487b...@newsgroups.borland.com...
>
> Got a bit of a conceptual question here. I have a piece of code that
> performs a recursive search of the users hard disk and generates a list of
> files. Nothing new here. My code is based around the FindFirstFile /
> FindNextFile API's. From what I can see, there doesn't seem to be a way
> to specify a wildcard search mask i.e. *.exe so it seems necessary to
> check for .exe extension within the search, which I do like this:
>
> AnsiString sFile = (AnsiString)fdFindFileData.cFileName;
> if (ExtractFileExt(sFile).AnsiCompareIC(".exe")== 0)
> // add to my list
> ...