From fb4489bded8691cab0fc8894e72fe014093f8b15 Mon Sep 17 00:00:00 2001 From: JaniruTEC Date: Sat, 9 May 2020 16:44:37 +0200 Subject: [PATCH] Added DesiredAccessMask and DiskSpaceInfo Added DesiredAccessMask to wrap parameter desiredAccess of DokanyFileSystem#zwCreateFile to aid in creating a wrapper ("EasyDokanFileSystem") for DokanyFileSystem Added DiskSpaceInfo to wrap the result of DokanyFileSystem#getDiskFreeSpace to aid in creating a wrapper ("EasyDokanFileSystem") for DokanyFileSystem This commit is part of my effort to fix dokan-java's issue 32 (https://github.com/dokan-dev/dokan-java/issues/32): Adding wrappers for high-level programming --- .../wrappers/DesiredAccessMask.java | 146 ++++++++++++++++++ .../dokan_java/wrappers/DiskSpaceInfo.java | 42 +++++ 2 files changed, 188 insertions(+) create mode 100644 src/main/java/dev/dokan/dokan_java/wrappers/DesiredAccessMask.java create mode 100644 src/main/java/dev/dokan/dokan_java/wrappers/DiskSpaceInfo.java diff --git a/src/main/java/dev/dokan/dokan_java/wrappers/DesiredAccessMask.java b/src/main/java/dev/dokan/dokan_java/wrappers/DesiredAccessMask.java new file mode 100644 index 0000000..83b54ee --- /dev/null +++ b/src/main/java/dev/dokan/dokan_java/wrappers/DesiredAccessMask.java @@ -0,0 +1,146 @@ +package dev.dokan.dokan_java.wrappers; + +import dev.dokan.dokan_java.constants.microsoft.AccessMask; +import dev.dokan.dokan_java.constants.microsoft.DirectoryAccessMask; +import dev.dokan.dokan_java.constants.microsoft.FileAccessMask; +import dev.dokan.dokan_java.constants.microsoft.FileAttribute; +import dev.dokan.dokan_java.structure.EnumIntegerSet; + +import java.util.concurrent.atomic.AtomicInteger; + +public class DesiredAccessMask { + + private final boolean isDirectory; + private final AtomicInteger accessMask; + + public DesiredAccessMask(int rawAccessMask, int rawFileAttributes) { + this(rawAccessMask, (rawFileAttributes & FileAttribute.DIRECTORY.getMask()) != 0); + } + + public DesiredAccessMask(int rawAccessMask, EnumIntegerSet fileAttributes) { + this(rawAccessMask, fileAttributes.contains(FileAttribute.DIRECTORY)); + } + + //TODO Check for illegal flags if isDirectory=true + //See https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-zwcreatefile Note below first table + public DesiredAccessMask(int rawAccessMask, boolean isDirectory) { + this.isDirectory = isDirectory; + this.accessMask = new AtomicInteger(rawAccessMask); + } + + public EnumIntegerSet getBasicRights() { + return EnumIntegerSet.enumSetFromInt(this.accessMask.get(), AccessMask.values()); + } + + public EnumIntegerSet getSpecificRights() { + return EnumIntegerSet.enumSetFromInt(this.accessMask.get(), FileAccessMask.values()); + } + + public boolean isDirectory() { + return this.isDirectory; + } + + public int getAccessMask() { + return this.accessMask.get(); + } + + public void setAccessMask(int accessMask) { + this.accessMask.set(accessMask); + } + + public boolean getFlag(AccessMask flag) { + return getFlag(flag.getMask()); + } + + public boolean getFlag(FileAccessMask flag) { + return getFlag(flag.getMask()); + } + + public boolean getFlag(DirectoryAccessMask flag) { + if(!this.isDirectory) { + throw new IllegalArgumentException("Not a directory!"); + } + return silentGetFlag(flag); + } + + public boolean silentGetFlag(DirectoryAccessMask flag) { + return getFlag(flag.getMask()); + } + + public boolean getFlag(int flag) { + return (this.accessMask.get() & flag) != 0; + } + + public boolean setFlag(AccessMask flag) { + return updateFlag(flag, true); + } + + public boolean unsetFlag(AccessMask flag) { + return updateFlag(flag, false); + } + + public boolean updateFlag(AccessMask flag, boolean value) { + return updateFlag(flag.getMask(), value); + } + + public boolean setFlag(FileAccessMask flag) { + return updateFlag(flag, true); + } + + public boolean unsetFlag(FileAccessMask flag) { + return updateFlag(flag, false); + } + + public boolean updateFlag(FileAccessMask flag, boolean value) { + return updateFlag(flag.getMask(), value); + } + + public boolean setFlag(DirectoryAccessMask flag) { + if(!this.isDirectory) { + throw new IllegalArgumentException("Not a directory!"); + } + return silentSetFlag(flag); + } + + public boolean unsetFlag(DirectoryAccessMask flag) { + if(!this.isDirectory) { + throw new IllegalArgumentException("Not a directory!"); + } + return silentUnsetFlag(flag); + } + + public boolean updateFlag(DirectoryAccessMask flag, boolean value) { + if(!this.isDirectory) { + throw new IllegalArgumentException("Not a directory!"); + } + return silentUpdateFlag(flag, value); + } + + public boolean silentSetFlag(DirectoryAccessMask flag) { + return silentUpdateFlag(flag, true); + } + + public boolean silentUnsetFlag(DirectoryAccessMask flag) { + return silentUpdateFlag(flag, false); + } + + public boolean silentUpdateFlag(DirectoryAccessMask flag, boolean value) { + return updateFlag(flag.getMask(), value); + } + + public boolean updateFlag(int flag, boolean value) { + int prev = this.accessMask.getAndUpdate(current -> current & (value ? flag : ~flag)); + return (prev & flag) != 0; + } + + private FileAccessMask getFileAccessMask(DirectoryAccessMask attribute) { + //This lookup is fine, but a different kind of mapping would be preferable + switch(attribute) { + case LIST_DIRECTORY: //1 + return FileAccessMask.READ_DATA; + case TRAVERSE: //32 + return FileAccessMask.EXECUTE; + } + throw new IllegalStateException(); + } +} \ No newline at end of file diff --git a/src/main/java/dev/dokan/dokan_java/wrappers/DiskSpaceInfo.java b/src/main/java/dev/dokan/dokan_java/wrappers/DiskSpaceInfo.java new file mode 100644 index 0000000..10196c2 --- /dev/null +++ b/src/main/java/dev/dokan/dokan_java/wrappers/DiskSpaceInfo.java @@ -0,0 +1,42 @@ +package dev.dokan.dokan_java.wrappers; + +public class DiskSpaceInfo { + + private long usableSpace; + private long totalSpace; + private long unallocatedSpace; + + public DiskSpaceInfo() { + this(0L, 0L, 0L); + } + + public DiskSpaceInfo(long usableSpace, long totalSpace, long unallocatedSpace) { + this.usableSpace = usableSpace; + this.totalSpace = totalSpace; + this.unallocatedSpace = unallocatedSpace; + } + + public long getUsableSpace() { + return this.usableSpace; + } + + public void setUsableSpace(long usableSpace) { + this.usableSpace = usableSpace; + } + + public long getTotalSpace() { + return this.totalSpace; + } + + public void setTotalSpace(long totalSpace) { + this.totalSpace = totalSpace; + } + + public long getUnallocatedSpace() { + return this.unallocatedSpace; + } + + public void setUnallocatedSpace(long unallocatedSpace) { + this.unallocatedSpace = unallocatedSpace; + } +} \ No newline at end of file