Skip to content

Commit

Permalink
Added DesiredAccessMask and DiskSpaceInfo
Browse files Browse the repository at this point in the history
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 (dokan-dev#32): Adding wrappers for high-level programming
  • Loading branch information
JaniruTEC committed May 9, 2020
1 parent a11aa0e commit fb4489b
Show file tree
Hide file tree
Showing 2 changed files with 188 additions and 0 deletions.
146 changes: 146 additions & 0 deletions src/main/java/dev/dokan/dokan_java/wrappers/DesiredAccessMask.java
Original file line number Diff line number Diff line change
@@ -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<FileAttribute> 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<AccessMask> getBasicRights() {
return EnumIntegerSet.enumSetFromInt(this.accessMask.get(), AccessMask.values());
}

public EnumIntegerSet<FileAccessMask> 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();
}
}
42 changes: 42 additions & 0 deletions src/main/java/dev/dokan/dokan_java/wrappers/DiskSpaceInfo.java
Original file line number Diff line number Diff line change
@@ -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;
}
}

0 comments on commit fb4489b

Please sign in to comment.