View Issue Details

IDProjectCategoryView StatusLast Update
0035773FPCRTLpublic2019-07-08 22:07
ReporterSerge AnvarovAssigned ToMarco van de Voort 
PrioritynormalSeverityminorReproducibilityhave not tried
Status resolvedResolutionfixed 
PlatformOSWindowsOS Version
Product Version3.3.1Product Build 
Target VersionFixed in Version 
Summary0035773: Reopen issue 0035742
DescriptionFindExInfoBasic does not solve the issue 0035742. In this case Windows still searches for short names.
See related issue.
Steps To Reproduce{$APPTYPE CONSOLE}
{$MODE OBJFPC}
{$LONGSTRINGS ON}

uses SysUtils;

procedure PrintFilesByMask(const InPath, Mask: string);
var
  SR: TSearchRec;
begin
  if FindFirst(IncludeTrailingPathDelimiter(InPath) + Mask, faAnyFile, SR) = 0 then
  try
    repeat
      if (SR.Attr and faDirectory) = 0 then
        Writeln(SR.Name, ' [', string(SR.FindData.cAlternateFileName), ']');
    until FindNext(SR) <> 0;
  finally
    SysUtils.FindClose(SR);
  end;
end;

begin
  PrintFilesByMask('c:\Temp', '*.odt');
  Readln;
end.

Result:
.-lock.c.odt# [-LOCKC~1.ODT]
a.odt []
b.odt []
c.odt []
TagsNo tags attached.
Fixed in Revision42326
FPCOldBugId
FPCTarget-
Attached Files

Activities

Marco van de Voort

2019-06-28 23:23

manager   ~0117001

Which windows? It will only work for w7+

Serge Anvarov

2019-06-29 16:46

reporter   ~0117005

Last edited: 2019-06-29 17:02

View 3 revisions

This result on Windows 7 x64. FPC 3.3.1 rev. 42293.
And in documentation https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-findfirstfilea it is indicated that "The search includes the long and short file names". Without any conditions or types of parameters.
Example on pure API:
{$APPTYPE CONSOLE}
{$MODE OBJFPC}
{$LONGSTRINGS ON}

uses Windows;

procedure PrintFilesByMask(const Mask: string);
var
  H: THandle;
  R: TWin32FindDataW;
begin
  H := FindFirstFileExW(PWideChar(UnicodeString(Mask)), FindExInfoBasic, @R, FindExSearchNameMatch, nil, 0);
  if H <> INVALID_HANDLE_VALUE then
  try
    repeat
      if (R.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) = 0 then
        Writeln(string(R.cFileName), ' [', string(R.cAlternateFileName), ']');
    until not FindNextFileW(H, R);
  finally
    FindClose(H);
  end;
end;

begin
  PrintFilesByMask('c:\Temp\*.odt');
  Readln;
end.

Result:
.-lock.c.odt# []
a.odt []
b.odt []
c.odt []

Max Nazhalov

2019-06-29 19:09

reporter   ~0117007

If You dissect the Mask from the base path first, the rest seems rather simple..
[not deeply tested though]

{$APPTYPE CONSOLE}
{$MODE OBJFPC}
{$LONGSTRINGS ON}

uses Windows, shlwapi;

procedure PrintFilesByMask(const Path, Mask: string);
var
  H: THandle;
  R: TWin32FindDataW;
begin
  H := FindFirstFileW(PWideChar(UnicodeString(Path+Mask)), @R);
  if H <> INVALID_HANDLE_VALUE then
  try
    repeat
      if not PathMatchSpecW(R.cFileName,PWideChar(UnicodeString(Mask))) then
        continue;
      if (R.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) = 0 then
        Writeln(string(R.cFileName), ' [', string(R.cAlternateFileName), ']');
    until not FindNextFileW(H, R);
  finally
    FindClose(H);
  end;
end;

begin
  PrintFilesByMask('.\','*.odt');
  Readln;
end.

---
PathMatchSpec is available since shlwapi.dll v4.71, so covers even Win95 with IE4

Max Nazhalov

2019-06-29 19:24

reporter   ~0117008

To play it safe, condition can be set ever stronger:
  if PathMatchSpecW(R.cAlternateFileName,PWideChar(UnicodeString(Mask))) and not PathMatchSpecW(R.cFileName,PWideChar(UnicodeString(Mask))) then
     continue; // really skip it

Marco van de Voort

2019-06-29 19:37

manager   ~0117009

Last edited: 2019-06-29 19:38

View 2 revisions

Note that we use findfirstEXW now, not findfirstA. And that lists: https://docs.microsoft.com/nl-nl/windows/desktop/api/minwinbase/ne-minwinbase-findex_info_levels

I can't test this with my regular systems that all seem to have sfn disabled. I'll see if I can dig something ancient out of the closet over the weekend.

I do feel that introducing a compare for every entry while the whole SFN circus is already winding down is disproportionate.

Max Nazhalov

2019-06-29 19:49

reporter   ~0117010

> Note that we use findfirstEXW now, not findfirstA.
Sadly, it doesn't work. Just tested on win7. While cAlternateFileName is empty on return, it plays the match, regardless how many "..Ex" and "..W" we append ;-)

Marco van de Voort

2019-07-03 12:03

manager   ~0117045

Last edited: 2019-07-03 12:04

View 2 revisions

Indeed. Anyway, I don't like to burden the core search routines with this triviality, specially since it is already this way for 22 years, if not longer, specially since MS could turn this default off any minute. (reminder to self: check freshly installed system)

Better have some specialized ones in some other unit for the few cases where it matters. Anyway I'll leave it open for now for others to comment on.

Max Nazhalov

2019-07-04 17:58

reporter   ~0117059

Then please reset the FindExInfoDefaults to FindExInfoStandard, since the new default (FindExInfoBasic) merely hides .cAlternateFileName achieving nothing..

Marco van de Voort

2019-07-04 18:15

manager   ~0117060

I don't understand what the exact problem is. What would that actually solve?

Max Nazhalov

2019-07-04 19:06

reporter   ~0117061

> Better have some specialized ones in some other unit for the few cases where it matters.

They can take care of SFN itself, if they want (and if it's ever available).
For now You cut them off.

Max Nazhalov

2019-07-04 19:14

reporter   ~0117062

Also note that intruducing such a global variable leads to a global race (within a given program)/

Marco van de Voort

2019-07-05 11:26

manager   ~0117072

I set it to standard for now. I wonder how a global var that is not exported, and only set during initialization leads to global races though

Max Nazhalov

2019-07-05 11:43

reporter   ~0117074

If any of the local/private thread will change it -- all the other [local/private] threads will unexpectedly get fired.
It is strictly local setting by it's design, so its global exposure is not a good idea, IMHO.
Better to use the default parameter in the function call, or even forget it at all, since it does nothing essential at all.

Marco van de Voort

2019-07-05 11:59

manager   ~0117077

No other code has access to it outside of sysutils since it is not exported. There is no "global" exposure.

With a default parameter, you can't make it dependent on the windows detection, what was the whole idea of this variable.

Max Nazhalov

2019-07-05 18:39

reporter   ~0117089

Yup, didn't notice the scope, my bad.. Objection withdrawn.

Marco van de Voort

2019-07-08 22:07

manager   ~0117118

Ok so close for now then

Issue History

Date Modified Username Field Change
2019-06-26 22:24 Serge Anvarov New Issue
2019-06-28 23:23 Marco van de Voort Note Added: 0117001
2019-06-29 16:46 Serge Anvarov Note Added: 0117005
2019-06-29 16:48 Serge Anvarov Note Edited: 0117005 View Revisions
2019-06-29 17:02 Serge Anvarov Note Edited: 0117005 View Revisions
2019-06-29 19:09 Max Nazhalov Note Added: 0117007
2019-06-29 19:24 Max Nazhalov Note Added: 0117008
2019-06-29 19:37 Marco van de Voort Note Added: 0117009
2019-06-29 19:38 Marco van de Voort Note Edited: 0117009 View Revisions
2019-06-29 19:49 Max Nazhalov Note Added: 0117010
2019-07-03 12:03 Marco van de Voort Note Added: 0117045
2019-07-03 12:04 Marco van de Voort Note Edited: 0117045 View Revisions
2019-07-04 17:58 Max Nazhalov Note Added: 0117059
2019-07-04 18:15 Marco van de Voort Note Added: 0117060
2019-07-04 19:06 Max Nazhalov Note Added: 0117061
2019-07-04 19:14 Max Nazhalov Note Added: 0117062
2019-07-05 11:13 Marco van de Voort Fixed in Revision => 42326
2019-07-05 11:13 Marco van de Voort FPCTarget => -
2019-07-05 11:26 Marco van de Voort Note Added: 0117072
2019-07-05 11:43 Max Nazhalov Note Added: 0117074
2019-07-05 11:59 Marco van de Voort Note Added: 0117077
2019-07-05 18:39 Max Nazhalov Note Added: 0117089
2019-07-08 22:07 Marco van de Voort Assigned To => Marco van de Voort
2019-07-08 22:07 Marco van de Voort Status new => resolved
2019-07-08 22:07 Marco van de Voort Resolution open => fixed
2019-07-08 22:07 Marco van de Voort Note Added: 0117118