From 29bea143df9d4e22db34b3ddbc8cfd06a1858537 Mon Sep 17 00:00:00 2001 From: infeo Date: Mon, 29 Apr 2019 15:17:56 +0200 Subject: [PATCH 1/7] closes #27 --- .../dokany/java/DokanyOperationsProxy.java | 175 +++++++++++++++--- 1 file changed, 147 insertions(+), 28 deletions(-) diff --git a/src/main/java/com/dokany/java/DokanyOperationsProxy.java b/src/main/java/com/dokany/java/DokanyOperationsProxy.java index 2040e23..27bc7d8 100644 --- a/src/main/java/com/dokany/java/DokanyOperationsProxy.java +++ b/src/main/java/com/dokany/java/DokanyOperationsProxy.java @@ -10,12 +10,16 @@ import com.sun.jna.platform.win32.WinBase; import com.sun.jna.ptr.IntByReference; import com.sun.jna.ptr.LongByReference; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Implementation of {@link com.dokany.java.DokanyOperations} which connects to {@link com.dokany.java.DokanyFileSystem}. */ final class DokanyOperationsProxy extends com.dokany.java.DokanyOperations { + private final static Logger LOG = LoggerFactory.getLogger(DokanyOperationsProxy.class); + private final DokanyFileSystem fileSystem; DokanyOperationsProxy(final DokanyFileSystem fileSystem) { @@ -55,12 +59,17 @@ public long callback(WString rawPath, WinBase.SECURITY_ATTRIBUTES securityContex IntByReference desiredAccess = new IntByReference(); IntByReference fileAttributeFlags = new IntByReference(); NativeMethods.DokanMapKernelToUserCreateFileFlags(rawDesiredAccess, rawFileAttributes, rawCreateOptions, rawCreateDisposition, desiredAccess, fileAttributeFlags, createDisposition); - int win32ErrorCode = fileSystem.zwCreateFile(rawPath, securityContext, desiredAccess.getValue(), fileAttributeFlags.getValue(), rawShareAccess, createDisposition.getValue(), rawCreateOptions, dokanyFileInfo); - //little cheat for issue #24 - if (win32ErrorCode == Win32ErrorCode.ERROR_INVALID_STATE.getMask()) { - return NtStatus.FILE_IS_A_DIRECTORY.getMask(); - } else { - return NativeMethods.DokanNtStatusFromWin32(win32ErrorCode); + try { + int win32ErrorCode = fileSystem.zwCreateFile(rawPath, securityContext, desiredAccess.getValue(), fileAttributeFlags.getValue(), rawShareAccess, createDisposition.getValue(), rawCreateOptions, dokanyFileInfo); + //little cheat for issue #24 + if (win32ErrorCode == Win32ErrorCode.ERROR_INVALID_STATE.getMask()) { + return NtStatus.FILE_IS_A_DIRECTORY.getMask(); + } else { + return NativeMethods.DokanNtStatusFromWin32(win32ErrorCode); + } + } catch (Exception e) { + LOG.warn("zwCreateFile(): Uncaught exception. Returning generic failure code.", e); + return NtStatus.UNSUCCESSFUL.getMask(); } } } @@ -77,7 +86,12 @@ class ReadFileProxy implements ReadFile { @Override public long callback(WString rawPath, Pointer rawBuffer, int rawBufferLength, IntByReference rawReadLength, long rawOffset, DokanyFileInfo dokanyFileInfo) { - return NativeMethods.DokanNtStatusFromWin32(fileSystem.readFile(rawPath, rawBuffer, rawBufferLength, rawReadLength, rawOffset, dokanyFileInfo)); + try { + return NativeMethods.DokanNtStatusFromWin32(fileSystem.readFile(rawPath, rawBuffer, rawBufferLength, rawReadLength, rawOffset, dokanyFileInfo)); + } catch (Exception e) { + LOG.warn("readFile(): Uncaught exception. Returning generic failure code.", e); + return NtStatus.UNSUCCESSFUL.getMask(); + } } } @@ -85,7 +99,12 @@ class WriteFileProxy implements WriteFile { @Override public long callback(WString rawPath, Pointer rawBuffer, int rawNumberOfBytesToWrite, IntByReference rawNumberOfBytesWritten, long rawOffset, DokanyFileInfo dokanyFileInfo) { - return NativeMethods.DokanNtStatusFromWin32(fileSystem.writeFile(rawPath, rawBuffer, rawNumberOfBytesToWrite, rawNumberOfBytesWritten, rawOffset, dokanyFileInfo)); + try { + return NativeMethods.DokanNtStatusFromWin32(fileSystem.writeFile(rawPath, rawBuffer, rawNumberOfBytesToWrite, rawNumberOfBytesWritten, rawOffset, dokanyFileInfo)); + } catch (Exception e) { + LOG.warn("writeFile(): Uncaught exception. Returning generic failure code.", e); + return NtStatus.UNSUCCESSFUL.getMask(); + } } } @@ -93,7 +112,12 @@ class FlushFileBuffersProxy implements FlushFileBuffers { @Override public long callback(WString rawPath, DokanyFileInfo dokanyFileInfo) { - return NativeMethods.DokanNtStatusFromWin32(fileSystem.flushFileBuffers(rawPath, dokanyFileInfo)); + try { + return NativeMethods.DokanNtStatusFromWin32(fileSystem.flushFileBuffers(rawPath, dokanyFileInfo)); + } catch (Exception e) { + LOG.warn("flushFileBuffers(): Uncaught exception. Returning generic failure code.", e); + return NtStatus.UNSUCCESSFUL.getMask(); + } } } @@ -101,7 +125,12 @@ class GetFileInformationProxy implements GetFileInformation { @Override public long callback(WString fileName, ByHandleFileInfo handleFileInfo, DokanyFileInfo dokanyFileInfo) { - return NativeMethods.DokanNtStatusFromWin32(fileSystem.getFileInformation(fileName, handleFileInfo, dokanyFileInfo)); + try { + return NativeMethods.DokanNtStatusFromWin32(fileSystem.getFileInformation(fileName, handleFileInfo, dokanyFileInfo)); + } catch (Exception e) { + LOG.warn("getFileInformation(): Uncaught exception. Returning generic failure code.", e); + return NtStatus.UNSUCCESSFUL.getMask(); + } } } @@ -109,7 +138,12 @@ class FindFilesProxy implements FindFiles { @Override public long callback(WString rawPath, FillWin32FindData rawFillFindData, DokanyFileInfo dokanyFileInfo) { - return NativeMethods.DokanNtStatusFromWin32(fileSystem.findFiles(rawPath, rawFillFindData, dokanyFileInfo)); + try { + return NativeMethods.DokanNtStatusFromWin32(fileSystem.findFiles(rawPath, rawFillFindData, dokanyFileInfo)); + } catch (Exception e) { + LOG.warn("findFiles(): Uncaught exception. Returning generic failure code.", e); + return NtStatus.UNSUCCESSFUL.getMask(); + } } } @@ -117,7 +151,12 @@ class FindFilesWithPatternProxy implements FindFilesWithPattern { @Override public long callback(WString fileName, WString searchPattern, FillWin32FindData rawFillFindData, DokanyFileInfo dokanyFileInfo) { - return NativeMethods.DokanNtStatusFromWin32(fileSystem.findFilesWithPattern(fileName, searchPattern, rawFillFindData, dokanyFileInfo)); + try { + return NativeMethods.DokanNtStatusFromWin32(fileSystem.findFilesWithPattern(fileName, searchPattern, rawFillFindData, dokanyFileInfo)); + } catch (Exception e) { + LOG.warn("findFilesWithPattern(): Uncaught exception. Returning generic failure code.", e); + return NtStatus.UNSUCCESSFUL.getMask(); + } } } @@ -125,7 +164,12 @@ class SetFileAttributesProxy implements SetFileAttributes { @Override public long callback(WString rawPath, int rawAttributes, DokanyFileInfo dokanyFileInfo) { - return NativeMethods.DokanNtStatusFromWin32(fileSystem.setFileAttributes(rawPath, rawAttributes, dokanyFileInfo)); + try { + return NativeMethods.DokanNtStatusFromWin32(fileSystem.setFileAttributes(rawPath, rawAttributes, dokanyFileInfo)); + } catch (Exception e) { + LOG.warn("setFileAttributes(): Uncaught exception. Returning generic failure code.", e); + return NtStatus.UNSUCCESSFUL.getMask(); + } } } @@ -133,7 +177,12 @@ class SetFileTimeProxy implements SetFileTime { @Override public long callback(WString rawPath, WinBase.FILETIME rawCreationTime, WinBase.FILETIME rawLastAccessTime, WinBase.FILETIME rawLastWriteTime, DokanyFileInfo dokanyFileInfo) { - return NativeMethods.DokanNtStatusFromWin32(fileSystem.setFileTime(rawPath, rawCreationTime, rawLastAccessTime, rawLastWriteTime, dokanyFileInfo)); + try { + return NativeMethods.DokanNtStatusFromWin32(fileSystem.setFileTime(rawPath, rawCreationTime, rawLastAccessTime, rawLastWriteTime, dokanyFileInfo)); + } catch (Exception e) { + LOG.warn("setFileTime(): Uncaught exception. Returning generic failure code.", e); + return NtStatus.UNSUCCESSFUL.getMask(); + } } } @@ -141,7 +190,12 @@ class DeleteFileProxy implements DeleteFile { @Override public long callback(WString rawPath, DokanyFileInfo dokanyFileInfo) { - return NativeMethods.DokanNtStatusFromWin32(fileSystem.deleteFile(rawPath, dokanyFileInfo)); + try { + return NativeMethods.DokanNtStatusFromWin32(fileSystem.deleteFile(rawPath, dokanyFileInfo)); + } catch (Exception e) { + LOG.warn("deleteFile(): Uncaught exception. Returning generic failure code.", e); + return NtStatus.UNSUCCESSFUL.getMask(); + } } } @@ -149,7 +203,12 @@ class DeleteDirectoryProxy implements DeleteDirectory { @Override public long callback(WString rawPath, DokanyFileInfo dokanyFileInfo) { - return NativeMethods.DokanNtStatusFromWin32(fileSystem.deleteDirectory(rawPath, dokanyFileInfo)); + try { + return NativeMethods.DokanNtStatusFromWin32(fileSystem.deleteDirectory(rawPath, dokanyFileInfo)); + } catch (Exception e) { + LOG.warn("deleteDirectory(): Uncaught exception. Returning generic failure code.", e); + return NtStatus.UNSUCCESSFUL.getMask(); + } } } @@ -157,7 +216,12 @@ class MoveFileProxy implements MoveFile { @Override public long callback(WString rawPath, WString rawNewFileName, boolean rawReplaceIfExisting, DokanyFileInfo dokanyFileInfo) { - return NativeMethods.DokanNtStatusFromWin32(fileSystem.moveFile(rawPath, rawNewFileName, rawReplaceIfExisting, dokanyFileInfo)); + try { + return NativeMethods.DokanNtStatusFromWin32(fileSystem.moveFile(rawPath, rawNewFileName, rawReplaceIfExisting, dokanyFileInfo)); + } catch (Exception e) { + LOG.warn("moveFile(): Uncaught exception. Returning generic failure code.", e); + return NtStatus.UNSUCCESSFUL.getMask(); + } } } @@ -165,7 +229,12 @@ class SetEndOfFileProxy implements SetEndOfFile { @Override public long callback(WString rawPath, long rawByteOffset, DokanyFileInfo dokanyFileInfo) { - return NativeMethods.DokanNtStatusFromWin32(fileSystem.setEndOfFile(rawPath, rawByteOffset, dokanyFileInfo)); + try { + return NativeMethods.DokanNtStatusFromWin32(fileSystem.setEndOfFile(rawPath, rawByteOffset, dokanyFileInfo)); + } catch (Exception e) { + LOG.warn("setEndOfFile(): Uncaught exception. Returning generic failure code.", e); + return NtStatus.UNSUCCESSFUL.getMask(); + } } } @@ -173,7 +242,12 @@ class SetAllocationSizeProxy implements SetAllocationSize { @Override public long callback(WString rawPath, long rawLength, DokanyFileInfo dokanyFileInfo) { - return NativeMethods.DokanNtStatusFromWin32(fileSystem.setAllocationSize(rawPath, rawLength, dokanyFileInfo)); + try { + return NativeMethods.DokanNtStatusFromWin32(fileSystem.setAllocationSize(rawPath, rawLength, dokanyFileInfo)); + } catch (Exception e) { + LOG.warn("setAllocationSize(): Uncaught exception. Returning generic failure code.", e); + return NtStatus.UNSUCCESSFUL.getMask(); + } } } @@ -181,7 +255,12 @@ class LockFileProxy implements LockFile { @Override public long callback(WString rawPath, long rawByteOffset, long rawLength, DokanyFileInfo dokanyFileInfo) { - return NativeMethods.DokanNtStatusFromWin32(fileSystem.lockFile(rawPath, rawByteOffset, rawLength, dokanyFileInfo)); + try { + return NativeMethods.DokanNtStatusFromWin32(fileSystem.lockFile(rawPath, rawByteOffset, rawLength, dokanyFileInfo)); + } catch (Exception e) { + LOG.warn("lockFile(): Uncaught exception. Returning generic failure code.", e); + return NtStatus.UNSUCCESSFUL.getMask(); + } } } @@ -189,7 +268,12 @@ class UnlockFileProxy implements UnlockFile { @Override public long callback(WString rawPath, long rawByteOffset, long rawLength, DokanyFileInfo dokanyFileInfo) { - return NativeMethods.DokanNtStatusFromWin32(fileSystem.unlockFile(rawPath, rawByteOffset, rawLength, dokanyFileInfo)); + try { + return NativeMethods.DokanNtStatusFromWin32(fileSystem.unlockFile(rawPath, rawByteOffset, rawLength, dokanyFileInfo)); + } catch (Exception e) { + LOG.warn("unlockFile(): Uncaught exception. Returning generic failure code.", e); + return NtStatus.UNSUCCESSFUL.getMask(); + } } } @@ -197,7 +281,12 @@ class GetDiskFreeSpaceProxy implements GetDiskFreeSpace { @Override public long callback(LongByReference freeBytesAvailable, LongByReference totalNumberOfBytes, LongByReference totalNumberOfFreeBytes, DokanyFileInfo dokanyFileInfo) { - return NativeMethods.DokanNtStatusFromWin32(fileSystem.getDiskFreeSpace(freeBytesAvailable, totalNumberOfBytes, totalNumberOfFreeBytes, dokanyFileInfo)); + try { + return NativeMethods.DokanNtStatusFromWin32(fileSystem.getDiskFreeSpace(freeBytesAvailable, totalNumberOfBytes, totalNumberOfFreeBytes, dokanyFileInfo)); + } catch (Exception e) { + LOG.warn("getDiskFreeSpace(): Uncaught exception. Returning generic failure code.", e); + return NtStatus.UNSUCCESSFUL.getMask(); + } } } @@ -205,7 +294,12 @@ class GetVolumeInformationProxy implements GetVolumeInformation { @Override public long callback(Pointer rawVolumeNameBuffer, int rawVolumeNameSize, IntByReference rawVolumeSerialNumber, IntByReference rawMaximumComponentLength, IntByReference rawFileSystemFlags, Pointer rawFileSystemNameBuffer, int rawFileSystemNameSize, DokanyFileInfo dokanyFileInfo) { - return NativeMethods.DokanNtStatusFromWin32(fileSystem.getVolumeInformation(rawVolumeNameBuffer, rawVolumeNameSize, rawVolumeSerialNumber, rawMaximumComponentLength, rawFileSystemFlags, rawFileSystemNameBuffer, rawFileSystemNameSize, dokanyFileInfo)); + try { + return NativeMethods.DokanNtStatusFromWin32(fileSystem.getVolumeInformation(rawVolumeNameBuffer, rawVolumeNameSize, rawVolumeSerialNumber, rawMaximumComponentLength, rawFileSystemFlags, rawFileSystemNameBuffer, rawFileSystemNameSize, dokanyFileInfo)); + } catch (Exception e) { + LOG.warn("getVolumeInformation(): Uncaught exception. Returning generic failure code.", e); + return NtStatus.UNSUCCESSFUL.getMask(); + } } } @@ -213,7 +307,12 @@ class MountedProxy implements Mounted { @Override public long mounted(DokanyFileInfo dokanyFileInfo) { - return NativeMethods.DokanNtStatusFromWin32(fileSystem.mounted(dokanyFileInfo)); + try { + return NativeMethods.DokanNtStatusFromWin32(fileSystem.mounted(dokanyFileInfo)); + } catch (Exception e) { + LOG.warn("mounted(): Uncaught exception. Returning generic failure code.", e); + return NtStatus.UNSUCCESSFUL.getMask(); + } } } @@ -221,7 +320,12 @@ class UnmountedProxy implements Unmounted { @Override public long unmounted(DokanyFileInfo dokanyFileInfo) { - return NativeMethods.DokanNtStatusFromWin32(fileSystem.unmounted(dokanyFileInfo)); + try { + return NativeMethods.DokanNtStatusFromWin32(fileSystem.unmounted(dokanyFileInfo)); + } catch (Exception e) { + LOG.warn("unmounted(): Uncaught exception. Returning generic failure code.", e); + return NtStatus.UNSUCCESSFUL.getMask(); + } } } @@ -229,7 +333,12 @@ class GetFileSecurityProxy implements GetFileSecurity { @Override public long callback(WString rawPath, int rawSecurityInformation, Pointer rawSecurityDescriptor, int rawSecurityDescriptorLength, IntByReference rawSecurityDescriptorLengthNeeded, DokanyFileInfo dokanyFileInfo) { - return NativeMethods.DokanNtStatusFromWin32(fileSystem.getFileSecurity(rawPath, rawSecurityInformation, rawSecurityDescriptor, rawSecurityDescriptorLength, rawSecurityDescriptorLengthNeeded, dokanyFileInfo)); + try { + return NativeMethods.DokanNtStatusFromWin32(fileSystem.getFileSecurity(rawPath, rawSecurityInformation, rawSecurityDescriptor, rawSecurityDescriptorLength, rawSecurityDescriptorLengthNeeded, dokanyFileInfo)); + } catch (Exception e) { + LOG.warn("getFileSecurity(): Uncaught exception. Returning generic failure code.", e); + return NtStatus.UNSUCCESSFUL.getMask(); + } } } @@ -237,7 +346,12 @@ class SetFileSecurityProxy implements SetFileSecurity { @Override public long callback(WString rawPath, int rawSecurityInformation, Pointer rawSecurityDescriptor, int rawSecurityDescriptorLength, DokanyFileInfo dokanyFileInfo) { - return NativeMethods.DokanNtStatusFromWin32(fileSystem.setFileSecurity(rawPath, rawSecurityInformation, rawSecurityDescriptor, rawSecurityDescriptorLength, dokanyFileInfo)); + try { + return NativeMethods.DokanNtStatusFromWin32(fileSystem.setFileSecurity(rawPath, rawSecurityInformation, rawSecurityDescriptor, rawSecurityDescriptorLength, dokanyFileInfo)); + } catch (Exception e) { + LOG.warn("setFileSecurity(): Uncaught exception. Returning generic failure code.", e); + return NtStatus.UNSUCCESSFUL.getMask(); + } } } @@ -245,7 +359,12 @@ class FindStreamsProxy implements FindStreams { @Override public long callback(WString rawPath, FillWin32FindStreamData rawFillFindData, DokanyFileInfo dokanyFileInfo) { - return NativeMethods.DokanNtStatusFromWin32(fileSystem.findStreams(rawPath, rawFillFindData, dokanyFileInfo)); + try { + return NativeMethods.DokanNtStatusFromWin32(fileSystem.findStreams(rawPath, rawFillFindData, dokanyFileInfo)); + } catch (Exception e) { + LOG.warn("findStreams(): Uncaught exception. Returning generic failure code.", e); + return NtStatus.UNSUCCESSFUL.getMask(); + } } } From b5dff910007c13eade7abec0a7aa95e131259055 Mon Sep 17 00:00:00 2001 From: infeo Date: Mon, 29 Apr 2019 15:22:35 +0200 Subject: [PATCH 2/7] improved logging message --- .../org/cryptomator/frontend/dokany/ReadWriteAdapter.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/cryptomator/frontend/dokany/ReadWriteAdapter.java b/src/main/java/org/cryptomator/frontend/dokany/ReadWriteAdapter.java index 6bbeba3..2a6a0d6 100644 --- a/src/main/java/org/cryptomator/frontend/dokany/ReadWriteAdapter.java +++ b/src/main/java/org/cryptomator/frontend/dokany/ReadWriteAdapter.java @@ -230,10 +230,10 @@ else if ((attr != null && attr.isReadOnly() || ((rawFileAttributes & FileAttribu } return returnCode.getMask(); } catch (FileAlreadyExistsException e) { - LOG.trace("Unable to open {}.", path); + LOG.trace("File {} already exists.", path); return Win32ErrorCode.ERROR_FILE_EXISTS.getMask(); } catch (NoSuchFileException e) { - LOG.trace("{} not found.", path); + LOG.trace("File {} not found.", path); return Win32ErrorCode.ERROR_FILE_NOT_FOUND.getMask(); } catch (AccessDeniedException e) { LOG.trace("zwCreateFile(): Access to file {} was denied.", path); From 29e6d5bda6f3c30234320cb195dc359d25e36468 Mon Sep 17 00:00:00 2001 From: infeo Date: Mon, 29 Apr 2019 15:26:34 +0200 Subject: [PATCH 3/7] fixing version description --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d34d4f9..4106035 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 org.cryptomator dokany-nio-adapter - 1.1.7 + 1.2.0-SNAPSHOT Access resources at a given NIO path via Dokany. Dokany-NIO Adapter https://github.com/cryptomator/dokany-nio-adapter From d59e3e13d3f3eaf2fb4c09c53a6cd85fb9b15244 Mon Sep 17 00:00:00 2001 From: infeo Date: Mon, 29 Apr 2019 15:37:23 +0200 Subject: [PATCH 4/7] bumping test dependency --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4106035..e9e7e09 100644 --- a/pom.xml +++ b/pom.xml @@ -121,7 +121,7 @@ org.cryptomator cryptofs - 1.8.1 + 1.8.2 test From c9139c7735ecf8d21142202794b0812295723b79 Mon Sep 17 00:00:00 2001 From: infeo Date: Wed, 8 May 2019 14:46:49 +0200 Subject: [PATCH 5/7] updating test dependency --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e9e7e09..1df3911 100644 --- a/pom.xml +++ b/pom.xml @@ -121,7 +121,7 @@ org.cryptomator cryptofs - 1.8.2 + 1.8.3 test From 111dc5ff2d11bedde2b031b36b22a1cbc9f71509 Mon Sep 17 00:00:00 2001 From: infeo Date: Wed, 8 May 2019 14:55:56 +0200 Subject: [PATCH 6/7] fixes #28 --- .../org/cryptomator/frontend/dokany/FileUtil.java | 15 +++++++++++++++ .../frontend/dokany/ReadWriteAdapter.java | 6 +++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/cryptomator/frontend/dokany/FileUtil.java b/src/main/java/org/cryptomator/frontend/dokany/FileUtil.java index a4dc8ae..23ec850 100644 --- a/src/main/java/org/cryptomator/frontend/dokany/FileUtil.java +++ b/src/main/java/org/cryptomator/frontend/dokany/FileUtil.java @@ -7,6 +7,7 @@ import com.dokany.java.constants.FileAttribute; import com.dokany.java.structure.EnumIntegerSet; import com.google.common.collect.Sets; +import com.sun.jna.platform.win32.WinBase; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -15,11 +16,16 @@ import java.nio.file.StandardOpenOption; import java.nio.file.attribute.DosFileAttributeView; import java.nio.file.attribute.DosFileAttributes; +import java.nio.file.attribute.FileTime; +import java.time.Instant; +import java.util.Optional; import java.util.Set; import java.util.stream.IntStream; public class FileUtil { + public static final Instant WINDOWS_EPOCH_START = Instant.parse("1601-01-01T00:00:00Z"); + static final FileAttribute[] supportedAttributeValuesToSet = new FileAttribute[]{FileAttribute.HIDDEN, FileAttribute.READONLY, FileAttribute.SYSTEM, FileAttribute.ARCHIVE}; private static final Logger LOG = LoggerFactory.getLogger(FileUtil.class); @@ -188,4 +194,13 @@ public static Set buildOpenOptions(EnumIntegerSet access return openOptions; } + public static Optional toFileTime(WinBase.FILETIME windowsTime) { + Instant instant = windowsTime.toDate().toInstant(); + if (instant.equals(WINDOWS_EPOCH_START)) { + return Optional.empty(); + } else { + return Optional.of(FileTime.from(instant)); + } + } + } diff --git a/src/main/java/org/cryptomator/frontend/dokany/ReadWriteAdapter.java b/src/main/java/org/cryptomator/frontend/dokany/ReadWriteAdapter.java index 2a6a0d6..67a5eb4 100644 --- a/src/main/java/org/cryptomator/frontend/dokany/ReadWriteAdapter.java +++ b/src/main/java/org/cryptomator/frontend/dokany/ReadWriteAdapter.java @@ -667,9 +667,9 @@ public int setFileTime(WString rawPath, WinBase.FILETIME rawCreationTime, WinBas } else { try (PathLock pathLock = lockManager.createPathLock(path.toString()).forReading(); DataLock dataLock = pathLock.lockDataForWriting()) { - FileTime lastModifiedTime = FileTime.fromMillis(rawLastWriteTime.toDate().getTime()); - FileTime lastAccessTime = FileTime.fromMillis(rawLastAccessTime.toDate().getTime()); - FileTime createdTime = FileTime.fromMillis(rawCreationTime.toDate().getTime()); + FileTime lastModifiedTime = FileUtil.toFileTime(rawLastWriteTime).orElse(null); + FileTime lastAccessTime = FileUtil.toFileTime(rawLastAccessTime).orElse(null); + FileTime createdTime = FileUtil.toFileTime(rawCreationTime).orElse(null); Files.getFileAttributeView(path, BasicFileAttributeView.class).setTimes(lastModifiedTime, lastAccessTime, createdTime); LOG.trace("({}) Successful updated Filetime for {}.", dokanyFileInfo.Context, path); return Win32ErrorCode.ERROR_SUCCESS.getMask(); From 135522cffbe0cb4483c15a533442ecbec127303e Mon Sep 17 00:00:00 2001 From: infeo Date: Wed, 8 May 2019 14:57:37 +0200 Subject: [PATCH 7/7] preparing 1.1.8 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1df3911..3ada128 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 org.cryptomator dokany-nio-adapter - 1.2.0-SNAPSHOT + 1.1.8 Access resources at a given NIO path via Dokany. Dokany-NIO Adapter https://github.com/cryptomator/dokany-nio-adapter