Search code examples
delphiwinapifindfirst

Why does FindFirst return file names that don't match the mask?


I pass the parameter value '*1.dat' to FindFirst, still the first file that the FindFirst() routine return is 46checks5.dat, very consistently.

Is this a known problem?

vpath:=trim(vpath);
result:=true;
try
  res:=findfirst(vpath+'\'+vmask,faarchive,search);    //vmask = *1.dat
  try 
    while res=0 do
    begin
      vlist.add(search.name);   //searchname returned is 46checks5.dat!!!
      res:=findnext(search);
    end;
  finally
    findclose(search);
  end;
except
  result:=false;
end;

Solution

  • The reason is that the file has a "long" name, i.e. with more than 8 characters. For such files Windows also creates "short" names, that usually are created in the form longna~1.dat and this short name is found via *1.dat wildcard.

    You can easily reproduce the same behaviour in command prompt in an empty directory:

    C:\TEMP>echo. > 46checks5.dat 
    C:\TEMP>dir /x *1.dat
     Volume in drive C has no label.
     Volume Serial Number is 5C09-D9DE
    
     Directory of C:\TEMP
    
    2011.04.15  21:37                 3 46CHEC~1.DAT 46checks5.dat
                   1 File(s)              3 bytes
    

    The documentation for FindFirstFile(), which is the underlying API for FindFirst states:

    The search includes the long and short file names.

    To workaround this issue, then, rather than using Delphi's wrapper to FindFirstFile(), call the Win32 API FindFirstFileEx(). Pass FindExInfoBasic to the fInfoLevelId parameter.