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
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
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
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
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
OK, thanks.
I will prepare a version for you to test ASAP to be sure this works before I release it.
- Phil
Thanks, I have prepared unit tests for it already :)
Excellent. Here is the new version to test (https://exiftool.org/exiftool-11.70.zip).
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
Hi Phil, I am having some trouble with my computer at the moment. Will test it first thing tomorrow.
/Andreas
Hi Andreas,
OK. I'll put a hold on the official release until I hear back from you.
- Phil
Hi Phil, my tests worked just fine.
Great work with the fix.
/Andreas
Great, thanks. Version 11.70 is now officially released.
- Phil
Thanks Phil :)