Sharing violation error for utf8 filenames in Windows

Started by Eriksson, October 09, 2019, 10:53:01 AM

Previous topic - Next topic

Eriksson

I have noticed a difference in the exiftool application when using unicode filenames versus ansi filenames.
If a utf8 file (example åäö.jpg) is open in another application with FileShare.Read then exiftools cannot process the file. The returned error is actually "file not found".
Opening a ansi file (example 001.jpg) while it is also opened by another application with FileShare.Read works just fine.

I believe there is an error on line 3885 of ExifTool.pm where it tries to open the file with dwShareMode=0 resulting in a ERROR_SHARING_VIOLATION.
my $wh = eval { Win32API::File::CreateFileW($file, $access, 0, [], $create, 0, []) };
It should probably be set to FILE_SHARE_READ=0x00000001 if $access is set to Win32API::File::GENERIC_READ() as that should allow it to open the file even if the file is currently open by any other application.

/Andreas

Phil Harvey

Hi Andreas,

Thanks for this report.

Did you try this change to verify that it works for you?

Also, if GENERIC_READ is changed to FILE_SHARE_READ, should GENERIC_WRITE also be changed to FILE_SHARE_WRITE?

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

Eriksson

I'm not that good with perl unfortunately.

GENERIC_WRITE should keep the share flag as 0 to prevent other applications from writing to the same file at the same time.

/Andreas

Phil Harvey

Hi Andreas,

I see.   dwShareMode is the 3rd parameter.  So you want me to do this?:

            my $wh = eval { Win32API::File::CreateFileW($file, $access, Win32API::File::FILE_SHARE_READ(), [], $create, 0, []) };

Should this also be done in the Exists() function, on line 3917?

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

Eriksson

 That should work if $mode = read.
my $wh = eval { Win32API::File::CreateFileW($file, $access, Win32API::File::FILE_SHARE_READ(), [], $create, 0, []) };

You should still do the following when exiftool needs to open the file for writing
my $wh = eval { Win32API::File::CreateFileW($file, $access, 0, [], $create, 0, []) };

Yes, you are correct about the Exists function, It looks like you can change
my $wh = eval { Win32API::File::CreateFileW($file,
                        Win32API::File::GENERIC_READ(), 0, [],
                        Win32API::File::OPEN_EXISTING(), 0, []) };
into
my $wh = eval { Win32API::File::CreateFileW($file,
                        Win32API::File::GENERIC_READ(), Win32API::File::FILE_SHARE_READ(), [],
                        Win32API::File::OPEN_EXISTING(), 0, []) };

/Andreas

Phil Harvey

OK, thanks.

I will prepare a version for you to test ASAP to be sure this works before I release it.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

Eriksson


Phil Harvey

Excellent.  Here is the new version to test.

What I did was this:

            my $share = 0;
            eval {
                $share = Win32API::File::FILE_SHARE_READ() unless $access & Win32API::File::GENERIC_WRITE();
            };
            my $wh = eval { Win32API::File::CreateFileW($file, $access, $share, [], $create, 0, []) };


- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

Eriksson

Hi Phil, I am having some trouble with my computer at the moment. Will test it first thing tomorrow.

/Andreas

Phil Harvey

Hi Andreas,

OK.  I'll put a hold on the official release until I hear back from you.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

Eriksson

Hi Phil, my tests worked just fine.

Great work with the fix.

/Andreas

Phil Harvey

Great, thanks.  Version 11.70 is now officially released.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).