SmbFile.canRead returns STATUS_SHARING_VIOLATION or STATUS_ACCESS_DENIED exceptions when the file is locally opened
zerikv opened this issue · comments
The method SmbFile.canRead()
throws the following exception, when the file is opened locally by another application.
com.hierynomus.mssmb2.SMBApiException: STATUS_SHARING_VIOLATION(3221225539/3221225539): Create failed for Temp\test.txt
at com.hierynomus.smbj.share.Share.receive(Share.java:335)
at com.hierynomus.smbj.share.Share.sendReceive(Share.java:319)
at com.hierynomus.smbj.share.Share.createFile(Share.java:134)
at com.hierynomus.smbj.share.DiskShare.open(DiskShare.java:55)
at com.xebialabs.overthere.smb.SmbFile.getAccessMask(SmbFile.java:114)
at com.xebialabs.overthere.smb.SmbFile.canRead(SmbFile.java:98)
...
To test this case I launch a pending command "more" on the file in a window cmd.exe:
e:\Temp>more test.txt
....
-- Next (42%) --
As reported by "handle.exe" (https://docs.microsoft.com/en-us/sysinternals/downloads/handle)
the file "E:\Temp\test.txt" is opened by the application more.com with a sharing access FILE_SHARE_READ
+ FILE_SHARE_WRITE
:
------------------------------------------------------------------------------
more.com pid: 9972 DOMAIN\USER
38: File (RW-) E:\Temp
94: File (R-D) C:\Windows\System32\fr-FR\ulib.dll.mui
9C: File (RW-) E:\Temp\test.txt
In this case the method SmbFile.canRead()
should returns true.
In the method SmbFile.getAccessMask()
the request access used for open the file is MAXIMUM_ALLOWED
,
that seems to high, when requesting only with the access GENERIC_READ
the file can be opened with success.
In the same way for the method SmbFile.canExecute()
we have to request the access GENERIC_EXECUTE
.
For the method SmbFile.canWrite()
with the access GENERIC_WRITE
we get an other exception:
com.hierynomus.mssmb2.SMBApiException: STATUS_ACCESS_DENIED(3221225506/3221225506): QueryInfo failed for SMB2FileId{persistentHandle=97 27 00 00 14 00 00 00}
at com.hierynomus.smbj.share.Share.receive(Share.java:335)
at com.hierynomus.smbj.share.Share.sendReceive(Share.java:319)
at com.hierynomus.smbj.share.Share.queryInfo(Share.java:161)
at com.hierynomus.smbj.share.DiskShare.getFileInformation(DiskShare.java:210)
at com.hierynomus.smbj.share.DiskEntry.getFileInformation(DiskEntry.java:60)
at com.hierynomus.smbj.share.DiskEntry.getFileInformation(DiskEntry.java:56)
at com.xebialabs.overthere.smb.SmbFile.getAccessMask(SmbFile.java:117)
at com.xebialabs.overthere.smb.SmbFile.canWrite(SmbFile.java:106)
....
The file has been successfully opened (with the SMB2 message CREATE) but the message QUERY_INFO failed.
I work out that the read access must be also requested in order that information about the file could be read.
So for SmbFile.canWrite
we have to request the access: GENERIC_READ
+ GENERIC_WRITE
.
Other case, if the account has no right on the file, SbmFile.canRead
cannot open the file and fails with the error STATUS_ACCESS_DENIED
.
I think in this case it's better to catch the exception and return false.
I'm preparing a PR for these issues.
Eric
Makes sense, thanks @zerikv!
If you've got any comments for SMBJ, don't hesitate to let me know 👍