From 98e1497c95b7a40cfbb025d0450afe3d5fd07c57 Mon Sep 17 00:00:00 2001 From: JaniruTEC Date: Thu, 28 May 2020 18:23:48 +0200 Subject: [PATCH] Added last basic API-Classes Added ForwardingFileSystem as delegator for method-calls between EasyDokanFileSystem-implementations and DokanFileSystem-API Added EasyDokanFileSystemStub as stub for implementations of EasyDokanFileSystem (similiar to DokanFileSystemStub) Added AbstractEasyDokanFileSystem as base class for implementations of EasyDokanFileSystem (similiar to AbstractDokanFileSystem) This commit is part of my effort to fix dokan-java's issue https://github.com/dokan-dev/dokan-java/issues/32 --- .../wrappers/AbstractEasyDokanFileSystem.java | 69 +++++ .../wrappers/EasyDokanFileSystemStub.java | 217 ++++++++++++++++ .../wrappers/ForwardingFileSystem.java | 241 ++++++++++++++++++ 3 files changed, 527 insertions(+) create mode 100644 src/main/java/dev/dokan/dokan_java/wrappers/AbstractEasyDokanFileSystem.java create mode 100644 src/main/java/dev/dokan/dokan_java/wrappers/EasyDokanFileSystemStub.java create mode 100644 src/main/java/dev/dokan/dokan_java/wrappers/ForwardingFileSystem.java diff --git a/src/main/java/dev/dokan/dokan_java/wrappers/AbstractEasyDokanFileSystem.java b/src/main/java/dev/dokan/dokan_java/wrappers/AbstractEasyDokanFileSystem.java new file mode 100644 index 0000000..352f217 --- /dev/null +++ b/src/main/java/dev/dokan/dokan_java/wrappers/AbstractEasyDokanFileSystem.java @@ -0,0 +1,69 @@ +package dev.dokan.dokan_java.wrappers; + +import dev.dokan.dokan_java.NativeName; +import dev.dokan.dokan_java.FileSystemInformation; +import dev.dokan.dokan_java.NotImplemented; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.Set; +import java.util.stream.Collectors; + +public abstract class AbstractEasyDokanFileSystem implements EasyDokanFileSystem { + + private final Set notImplementedMethods; + private final ForwardingFileSystem lowLevelFS; + + public AbstractEasyDokanFileSystem(FileSystemInformation fileSystemInformation) { + this.notImplementedMethods = Arrays.stream(getClass().getMethods()) + .filter(method -> method.getAnnotation(NotImplemented.class) != null) + .map((method) -> getNativeName(method)) + .collect(Collectors.toSet()); + + this.lowLevelFS = new ForwardingFileSystem(fileSystemInformation, this.notImplementedMethods, this); + } + + private String getNativeName(Method method) { + Method annotated = getAnnotatedMethod(NativeName.class, method); + + if(annotated == null) { + return method.getName(); + } + return annotated.getAnnotation(NativeName.class).value(); + } + + private Method getAnnotatedMethod(Class annotation, Method method) { + return getAnnotatedMethod(annotation, method.getDeclaringClass(), method.getName(), method.getParameterTypes()); + } + + private Method getAnnotatedMethod(Class annotation, + Class inClass, + String methodName, + Class... parameterTypes) { + + Method result; + try { + result = inClass.getMethod(methodName, parameterTypes); + } catch(NoSuchMethodException e) { + return null; + } + + if(result.isAnnotationPresent(annotation)) { + return result; + } + + Class superClass = inClass.getSuperclass(); + if(superClass != null) { + result = getAnnotatedMethod(annotation, superClass, methodName, parameterTypes); + } + + if(result != null) { + return result; + } + + return Arrays.stream(inClass.getInterfaces()) + .map((cInterface) -> getAnnotatedMethod(annotation, cInterface, methodName, parameterTypes)) + .findFirst().orElse(null); + } +} diff --git a/src/main/java/dev/dokan/dokan_java/wrappers/EasyDokanFileSystemStub.java b/src/main/java/dev/dokan/dokan_java/wrappers/EasyDokanFileSystemStub.java new file mode 100644 index 0000000..1758715 --- /dev/null +++ b/src/main/java/dev/dokan/dokan_java/wrappers/EasyDokanFileSystemStub.java @@ -0,0 +1,217 @@ +package dev.dokan.dokan_java.wrappers; + +import dev.dokan.dokan_java.FileSystemInformation; +import dev.dokan.dokan_java.NotImplemented; +import dev.dokan.dokan_java.constants.microsoft.CreateOption; +import dev.dokan.dokan_java.constants.microsoft.CreationDisposition; +import dev.dokan.dokan_java.constants.microsoft.FileAttribute; +import dev.dokan.dokan_java.constants.microsoft.FileShareAccess; +import dev.dokan.dokan_java.structure.EnumIntegerSet; +import dev.dokan.dokan_java.structure.filesecurity.SelfRelativeSecurityDescriptor; + +import java.nio.file.Path; +import java.nio.file.attribute.FileTime; +import java.util.Collection; + +public class EasyDokanFileSystemStub extends AbstractEasyDokanFileSystem { + + public EasyDokanFileSystemStub(FileSystemInformation fileSystemInformation) { + super(fileSystemInformation); + } + + @NotImplemented + @Override + public void createHandle(Path absolutePath, + String relativePath, + EasyDokanIOSecurityContext securityContext, + DesiredAccessMask desiredAccess, + EnumIntegerSet fileAttributes, + EnumIntegerSet shareAccess, + CreationDisposition creationDisposition, + EnumIntegerSet createOptions, + DokanFileHandle dokanFileHandle) { + + } + + @NotImplemented + @Override + public void cleanup(Path absolutePath, String relativePath, DokanFileHandle dokanFileHandle) { + + } + + @NotImplemented + @Override + public void closeHandle(Path absolutePath, String relativePath, DokanFileHandle dokanFileHandle) { + + } + + @NotImplemented + @Override + public byte[] readFile(Path absolutePath, + String relativePath, + long offset, + int readLength, + DokanFileHandle dokanFileHandle) { + return new byte[0]; + } + + @NotImplemented + @Override + public int writeFile(Path absolutePath, + String relativePath, + byte[] buffer, + long offset, + DokanFileHandle dokanFileHandle) { + return 0; + } + + @NotImplemented + @Override + public void flush(Path absolutePath, String relativePath, DokanFileHandle dokanFileHandle) { + + } + + @NotImplemented + @Override + public EasyFileInfo getFileInformation(Path absolutePath, String relativePath, DokanFileHandle dokanFileHandle) { + return null; + } + + @NotImplemented + @Override + public Collection findFiles(Path absolutePath, String relativePath, DokanFileHandle dokanFileHandle) { + return null; + } + + @NotImplemented + @Override + public Collection findFilesWithPattern(Path absolutePath, + String relativePath, + String pattern, + DokanFileHandle dokanFileHandle) { + return null; + } + + @NotImplemented + @Override + public void setFileAttributes(Path absolutePath, + String relativePath, + EnumIntegerSet fileAttributes, + DokanFileHandle dokanFileHandle) { + + } + + @NotImplemented + @Override + public void setFileTime(Path absolutePath, + String relativePath, + FileTime creationTime, + FileTime lastAccessTime, + FileTime lastWriteTime, + DokanFileHandle dokanFileHandle) { + + } + + @NotImplemented + @Override + public void prepareDeleteFile(Path absolutePath, String relativePath, DokanFileHandle dokanFileHandle) { + + } + + @NotImplemented + @Override + public void prepareDeleteDirectory(Path absolutePath, String relativePath, DokanFileHandle dokanFileHandle) { + + } + + @NotImplemented + @Override + public void moveFile(Path sourceAbsolutePath, + String sourceRelativePath, + Path destinationAbsolutePath, + String destinationRelativePath, + boolean replaceIfExisting, + DokanFileHandle dokanFileHandle) { + + } + + @NotImplemented + @Override + public void setEndOfFile(Path absolutePath, String relativePath, long fileSize, DokanFileHandle dokanFileHandle) { + + } + + @NotImplemented + @Override + public void setAllocationSize(Path absolutePath, + String relativePath, + long allocationSize, + DokanFileHandle dokanFileHandle) { + + } + + @NotImplemented + @Override + public void lockFile(Path absolutePath, + String relativePath, + long lockOffset, + long lockLength, + DokanFileHandle dokanFileHandle) { + + } + + @NotImplemented + @Override + public void unlockFile(Path absolutePath, + String relativePath, + long lockOffset, + long lockLength, + DokanFileHandle dokanFileHandle) { + + } + + @NotImplemented + @Override + public DiskSpaceInfo getDiskSpaceInfo(DokanFileHandle dokanFileHandle) { + return null; + } + + @NotImplemented + @Override + public VolumeInformation getVolumeInformation(DokanFileHandle dokanFileHandle) { + return null; + } + + @NotImplemented + @Override + public void mounted(DokanFileHandle dokanFileHandle) { + + } + + @NotImplemented + @Override + public void unmounted(DokanFileHandle dokanFileHandle) { + + } + + @NotImplemented + @Override + public SelfRelativeSecurityDescriptor getFileSecurity(Path absolutePath, + String relativePath, + DesiredAccessMask requestedDescriptorInfo, + int availableLength, + DokanFileHandle dokanFileHandle) { + return null; + } + + @NotImplemented + @Override + public void setFileSecurity(Path absolutePath, + String relativePath, + DesiredAccessMask suppliedDescriptorInfo, + SelfRelativeSecurityDescriptor securityDescriptor, + int availableLength, + DokanFileHandle dokanFileHandle) { + + } +} diff --git a/src/main/java/dev/dokan/dokan_java/wrappers/ForwardingFileSystem.java b/src/main/java/dev/dokan/dokan_java/wrappers/ForwardingFileSystem.java new file mode 100644 index 0000000..2cbcb75 --- /dev/null +++ b/src/main/java/dev/dokan/dokan_java/wrappers/ForwardingFileSystem.java @@ -0,0 +1,241 @@ +package dev.dokan.dokan_java.wrappers; + + +import com.sun.jna.Pointer; +import com.sun.jna.WString; +import com.sun.jna.platform.win32.WinBase; +import com.sun.jna.ptr.IntByReference; +import com.sun.jna.ptr.LongByReference; +import dev.dokan.dokan_java.AbstractDokanFileSystem; +import dev.dokan.dokan_java.DokanException; +import dev.dokan.dokan_java.DokanOperations; +import dev.dokan.dokan_java.FileSystemInformation; +import dev.dokan.dokan_java.constants.microsoft.Win32ErrorCodes; +import dev.dokan.dokan_java.structure.ByHandleFileInformation; +import dev.dokan.dokan_java.structure.DokanFileInfo; +import dev.dokan.dokan_java.structure.DokanIOSecurityContext; + +import java.nio.file.Path; +import java.util.Set; + + +public class ForwardingFileSystem extends AbstractDokanFileSystem { + + private final Set notImplementedMethods; + private final AbstractEasyDokanFileSystem creator; + + public ForwardingFileSystem(FileSystemInformation fileSystemInformation, Set notImplementedMethods, AbstractEasyDokanFileSystem target) { + super(fileSystemInformation); + this.notImplementedMethods = notImplementedMethods; + this.creator = target; + } + + @Override + public boolean isImplemented(String funcName) { + return !this.notImplementedMethods.contains(funcName); + } + + + @Override + public int zwCreateFile(WString rawPath, DokanIOSecurityContext securityContext, int rawDesiredAccess, int rawFileAttributes, int rawShareAccess, int rawCreateDisposition, int rawCreateOptions, DokanFileInfo dokanFileInfo) { + return 0; + } + + @Override + public void cleanup(WString rawPath, DokanFileInfo dokanFileInfo) { + + } + + @Override + public void closeFile(WString rawPath, DokanFileInfo dokanFileInfo) { + + } + + @Override + public int readFile(WString rawPath, + Pointer rawBuffer, + int rawBufferLength, + IntByReference rawReadLength, + long rawOffset, + DokanFileInfo dokanFileInfo) { + return 0; + } + + @Override + public int writeFile(WString rawPath, + Pointer rawBuffer, + int rawNumberOfBytesToWrite, + IntByReference rawNumberOfBytesWritten, + long rawOffset, + DokanFileInfo dokanFileInfo) { + return 0; + } + + @Override + public int flushFileBuffers(WString rawPath, DokanFileInfo dokanFileInfo) { + return 0; + } + + @Override + public int getFileInformation(WString fileName, + ByHandleFileInformation handleFileInfo, + DokanFileInfo dokanFileInfo) { + return 0; + } + + @Override + public int findFiles(WString rawPath, + DokanOperations.FillWin32FindData rawFillFindData, + DokanFileInfo dokanFileInfo) { + return 0; + } + + @Override + public int findFilesWithPattern(WString fileName, + WString searchPattern, + DokanOperations.FillWin32FindData rawFillFindData, + DokanFileInfo dokanFileInfo) { + return 0; + } + + @Override + public int setFileAttributes(WString rawPath, int rawAttributes, DokanFileInfo dokanFileInfo) { + return 0; + } + + @Override + public int setFileTime(WString rawPath, + WinBase.FILETIME rawCreationTime, + WinBase.FILETIME rawLastAccessTime, + WinBase.FILETIME rawLastWriteTime, + DokanFileInfo dokanFileInfo) { + return 0; + } + + @Override + public int deleteFile(WString rawPath, DokanFileInfo dokanFileInfo) { + return 0; + } + + @Override + public int deleteDirectory(WString rawPath, DokanFileInfo dokanFileInfo) { + return 0; + } + + @Override + public int moveFile(WString rawPath, + WString rawNewFileName, + boolean rawReplaceIfExisting, + DokanFileInfo dokanFileInfo) { + return 0; + } + + @Override + public int setEndOfFile(WString rawPath, long rawByteOffset, DokanFileInfo dokanFileInfo) { + return 0; + } + + @Override + public int setAllocationSize(WString rawPath, long rawLength, DokanFileInfo dokanFileInfo) { + return 0; + } + + @Override + public int lockFile(WString rawPath, long rawByteOffset, long rawLength, DokanFileInfo dokanFileInfo) { + return 0; + } + + @Override + public int unlockFile(WString rawPath, long rawByteOffset, long rawLength, DokanFileInfo dokanFileInfo) { + return 0; + } + + @Override + public int getDiskFreeSpace(LongByReference freeBytesAvailable, + LongByReference totalNumberOfBytes, + LongByReference totalNumberOfFreeBytes, + DokanFileInfo dokanFileInfo) { + return 0; + } + + @Override + public int getVolumeInformation(Pointer rawVolumeNameBuffer, + int rawVolumeNameSize, + IntByReference rawVolumeSerialNumber, + IntByReference rawMaximumComponentLength, + IntByReference rawFileSystemFlags, + Pointer rawFileSystemNameBuffer, + int rawFileSystemNameSize, + DokanFileInfo dokanFileInfo) { + return 0; + } + + @Override + public int mounted(DokanFileInfo dokanFileInfo) { + return 0; + } + + @Override + public int unmounted(DokanFileInfo dokanFileInfo) { + return 0; + } + + @Override + public int getFileSecurity(WString rawPath, + int rawSecurityInformation, + Pointer rawSecurityDescriptor, + int rawSecurityDescriptorLength, + IntByReference rawSecurityDescriptorLengthNeeded, + DokanFileInfo dokanFileInfo) { + return 0; + } + + @Override + public int setFileSecurity(WString rawPath, + int rawSecurityInformation, + Pointer rawSecurityDescriptor, + int rawSecurityDescriptorLength, + DokanFileInfo dokanFileInfo) { + return 0; + } + + @Override + public void fillWin32FindData(WinBase.WIN32_FIND_DATA rawFillFindData, DokanFileInfo dokanFileInfo) { + + } + + @Override + public int findStreams(WString rawPath, + DokanOperations.FillWin32FindStreamData rawFillFindData, + DokanFileInfo dokanFileInfo) { + return 0; + } + + private int handleException(DokanException exc) { //TODO Reformat to allow any kind of exception + if (exc == null) { + return Win32ErrorCodes.ERROR_GEN_FAILURE; + } + + if (exc.getErrorCode() == Integer.MIN_VALUE) { + //TODO + } + //TODO Log + return exc.getErrorCode(); + } + + private String resolveRelativePath(WString path) { + return resolveRelativePath(path.toString()); + } + + private String resolveRelativePath(String path) { + return path; + } + + private Path resolveAbsolutePath(WString path) { + return resolveAbsolutePath(path.toString()); + } + + private Path resolveAbsolutePath(String path) { + return null; //TODO Implement + } +} \ No newline at end of file