diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6fe0b37..36fde6c 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,42 +1,25 @@ name: Build - on: [push] - jobs: build: name: Build and Test runs-on: ubuntu-latest - #This check is case insensitive if: "!contains(github.event.head_commit.message, '[ci skip]') && !contains(github.event.head_commit.message, '[skip ci]')" - env: - BUILD_VERSION: SNAPSHOT - # Name of the project; used in multiple steps (e.g. for upload) - PROJECT_NAME: dokany-nio-adapter steps: - # Foreign Action: Checkout the current commit - uses: actions/checkout@v2 - # Foreign Action: Setup Java Runtime Environment - uses: actions/setup-java@v1 with: java-version: 11 - server-id: bintray-jcenter - server-username: BINTRAY_USERNAME # Defined in step "deploytojcenter" - server-password: BINTRAY_API_KEY # See above - uses: actions/cache@v2 with: path: ~/.m2/repository - key: maven-${{ hashFiles('**/pom.xml') }} - restore-keys: maven- + key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} + restore-keys: | + ${{ runner.os }}-maven- - name: Ensure to use tagged version - id: taggedVersion + if: startsWith(github.ref, 'refs/tags/') run: mvn versions:set --file ./pom.xml -DnewVersion=${GITHUB_REF##*/} - if: startsWith(github.ref, 'refs/tags/') # Run if ref is tagged (e.g. "1.4") - - name: Export the project version to the job environment - id: setVersion # Output used above (outputs.artifact-version) - run: | - v=$(mvn help:evaluate "-Dexpression=project.version" -q -DforceStdout) - echo "BUILD_VERSION=${v}" >> $GITHUB_ENV - name: Build and Test id: buildAndTest run: mvn -B clean install jacoco:report -Pcoverage,dependency-check @@ -46,16 +29,16 @@ jobs: env: CODACY_PROJECT_TOKEN: ${{ secrets.CODACY_PROJECT_TOKEN }} continue-on-error: true - - name: Upload snapshot artifact ${{ env.PROJECT_NAME }}-${{ env.BUILD_VERSION }}.jar - id: uploadSnapshot - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v2 with: - name: ${{ env.PROJECT_NAME }}-${{ env.BUILD_VERSION }}.jar - path: target/${{ env.PROJECT_NAME }}-*.jar - - name: Deploy to jcenter - id: deployToJcenter - run: mvn -B deploy -Prelease -DskipTests - if: startsWith(github.ref, 'refs/tags/') # Run if ref is tagged (e.g. "v.1.4") + name: artifacts + path: target/*.jar + - name: Create Release + uses: actions/create-release@v1 + if: startsWith(github.ref, 'refs/tags/') env: - BINTRAY_USERNAME: cryptobot - BINTRAY_API_KEY: ${{ secrets.BINTRAY_API_KEY }} \ No newline at end of file + GITHUB_TOKEN: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }} # release as "cryptobot" + with: + tag_name: ${{ github.ref }} + release_name: Release ${{ github.ref }} + prerelease: true \ No newline at end of file diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 0000000..a46ddd6 --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,37 @@ + +name: "CodeQL" + +on: + push: + branches: [develop, main] + pull_request: + branches: [develop] + schedule: + - cron: '0 8 * * 0' + +jobs: + analyse: + name: Analyse + runs-on: ubuntu-latest + if: "!contains(github.event.head_commit.message, '[ci skip]') && !contains(github.event.head_commit.message, '[skip ci]')" + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 2 + - uses: actions/setup-java@v1 + with: + java-version: 11 + - uses: actions/cache@v2 + with: + path: ~/.m2/repository + key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} + restore-keys: | + ${{ runner.os }}-maven- + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: java + - name: Build + run: mvn -B compile + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 \ No newline at end of file diff --git a/.github/workflows/publish-central.yml b/.github/workflows/publish-central.yml new file mode 100644 index 0000000..f22b7a9 --- /dev/null +++ b/.github/workflows/publish-central.yml @@ -0,0 +1,37 @@ +name: Publish to Maven Central +on: + workflow_dispatch: + inputs: + tag: + description: 'Tag' + required: true + default: '0.0.0' +jobs: + publish: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + ref: "refs/tags/${{ github.event.inputs.tag }}" + - uses: actions/setup-java@v1 + with: + java-version: 11 + server-id: ossrh # Value of the distributionManagement/repository/id field of the pom.xml + server-username: MAVEN_USERNAME # env variable for username in deploy + server-password: MAVEN_PASSWORD # env variable for token in deploy + gpg-private-key: ${{ secrets.RELEASES_GPG_PRIVATE_KEY }} # Value of the GPG private key to import + gpg-passphrase: MAVEN_GPG_PASSPHRASE # env variable for GPG private key passphrase + - uses: actions/cache@v2 + with: + path: ~/.m2/repository + key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} + restore-keys: | + ${{ runner.os }}-maven- + - name: Enforce project version ${{ github.event.inputs.tag }} + run: mvn versions:set -B -DnewVersion=${{ github.event.inputs.tag }} + - name: Deploy + run: mvn deploy -B -DskipTests -Psign,deploy-central --no-transfer-progress + env: + MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }} + MAVEN_PASSWORD: ${{ secrets.OSSRH_PASSWORD }} + MAVEN_GPG_PASSPHRASE: ${{ secrets.RELEASES_GPG_PASSPHRASE }} \ No newline at end of file diff --git a/.github/workflows/publish-github.yml b/.github/workflows/publish-github.yml new file mode 100644 index 0000000..32a3041 --- /dev/null +++ b/.github/workflows/publish-github.yml @@ -0,0 +1,40 @@ +name: Publish to GitHub Packages +on: + release: + types: [published] +jobs: + publish: + runs-on: ubuntu-latest + if: startsWith(github.ref, 'refs/tags/') # only allow publishing tagged versions + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-java@v1 + with: + java-version: 11 + gpg-private-key: ${{ secrets.RELEASES_GPG_PRIVATE_KEY }} # Value of the GPG private key to import + gpg-passphrase: MAVEN_GPG_PASSPHRASE # env variable for GPG private key passphrase + - uses: actions/cache@v2 + with: + path: ~/.m2/repository + key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} + restore-keys: | + ${{ runner.os }}-maven- + - name: Enforce project version ${{ github.event.release.tag_name }} + run: mvn versions:set -B -DnewVersion=${{ github.event.release.tag_name }} + - name: Deploy + run: mvn deploy -B -DskipTests -Psign,deploy-github --no-transfer-progress + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + MAVEN_GPG_PASSPHRASE: ${{ secrets.RELEASES_GPG_PASSPHRASE }} + - name: Slack Notification + uses: rtCamp/action-slack-notify@v2 + env: + SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }} + SLACK_USERNAME: 'Cryptobot' + SLACK_ICON: + SLACK_ICON_EMOJI: ':bot:' + SLACK_CHANNEL: 'cryptomator-desktop' + SLACK_TITLE: "Published ${{ github.event.repository.name }} ${{ github.event.release.tag_name }}" + SLACK_MESSAGE: "Ready to ." + SLACK_FOOTER: + MSG_MINIMAL: true \ No newline at end of file diff --git a/pom.xml b/pom.xml index abda42b..504bffc 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 org.cryptomator dokany-nio-adapter - 1.2.3 + 1.2.4 Access resources at a given NIO path via Dokany. Dokany-NIO Adapter https://github.com/cryptomator/dokany-nio-adapter @@ -21,8 +21,8 @@ 1.7.27 1.2.3 30.0-jre - 5.6.0 - 5.5.0 + 5.7.0 + 5.7.0 1.4 @@ -55,13 +55,6 @@ - - - jcenter - https://jcenter.bintray.com/ - - - @@ -138,28 +131,57 @@ - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.8.0 - - - org.apache.maven.plugins - maven-surefire-plugin - 2.22.2 - - - - org.apache.maven.plugins maven-compiler-plugin + 3.8.1 + + true + - org.apache.maven.plugins maven-surefire-plugin + 2.22.2 + + + org.apache.maven.plugins + maven-jar-plugin + 3.2.0 + + + + org.cryptomator.frontend.dokany + + + + + + maven-source-plugin + 3.2.1 + + + attach-sources + + jar-no-fork + + + + + + maven-javadoc-plugin + 3.2.0 + + + attach-javadocs + + jar + + + + + none + com.dokany.java + @@ -172,7 +194,7 @@ org.owasp dependency-check-maven - 6.0.3 + 6.1.0 24 0 @@ -201,7 +223,7 @@ org.jacoco jacoco-maven-plugin - 0.8.3 + 0.8.6 prepare-agent @@ -222,45 +244,67 @@ - release - - - bintray-jcenter - https://api.bintray.com/maven/cryptomator/maven/dokany-nio-adapter/;publish=1 - - + sign - maven-source-plugin - 3.0.1 + maven-gpg-plugin + 1.6 - attach-sources + sign-artifacts + verify - jar-no-fork + sign + + + --pinentry-mode + loopback + + + + + + + + deploy-central + + + ossrh + Maven Central + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + + + - maven-javadoc-plugin - 3.0.1 - - - attach-javadocs - - jar - - - + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.8 + true - none - com.dokany.java + ossrh + https://oss.sonatype.org/ + true + + + deploy-github + + + github + GitHub Packages + https://maven.pkg.github.com/cryptomator/dokany-nio-adapter + + + diff --git a/src/main/java/com/dokany/java/DokanyUtils.java b/src/main/java/com/dokany/java/DokanyUtils.java index cdbec6a..6a009be 100644 --- a/src/main/java/com/dokany/java/DokanyUtils.java +++ b/src/main/java/com/dokany/java/DokanyUtils.java @@ -3,8 +3,6 @@ import com.dokany.java.constants.EnumInteger; import com.dokany.java.structure.EnumIntegerSet; import com.sun.jna.platform.win32.WinBase.FILETIME; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import java.util.Date; @@ -13,7 +11,6 @@ */ public class DokanyUtils { - private static final Logger LOG = LoggerFactory.getLogger(DokanyUtils.class); private DokanyUtils() { diff --git a/src/main/java/com/dokany/java/NativeMethods.java b/src/main/java/com/dokany/java/NativeMethods.java index 3ce6712..859cc90 100644 --- a/src/main/java/com/dokany/java/NativeMethods.java +++ b/src/main/java/com/dokany/java/NativeMethods.java @@ -5,15 +5,12 @@ import com.sun.jna.Native; import com.sun.jna.WString; import com.sun.jna.ptr.IntByReference; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; /** * Native API to the kernel Dokany driver. This is an internal class and should not be used directly by code outside com.dokany.java. */ public class NativeMethods { - private static final Logger LOG = LoggerFactory.getLogger(NativeMethods.class); private static final String DOKAN_DLL = "dokan1"; static { diff --git a/src/main/java/com/dokany/java/structure/ByHandleFileInfo.java b/src/main/java/com/dokany/java/structure/ByHandleFileInfo.java index be0ab6d..606fb6d 100644 --- a/src/main/java/com/dokany/java/structure/ByHandleFileInfo.java +++ b/src/main/java/com/dokany/java/structure/ByHandleFileInfo.java @@ -30,45 +30,48 @@ */ public class ByHandleFileInfo extends Structure implements Structure.ByReference { + /* + DWORD nNumberOfLinks; + DWORD nFileIndexHigh; + DWORD nFileIndexLow; AtomicLong counter = new AtomicLong(); + */ // Used to store actual values (instead of high/low) which can be retrieved using getter method - String filePath; long fileIndex; long fileSize; - /** - * The high-order DWORD value of the file size, in bytes. This value is zero unless the file size is greater than MAXDWORD. The size of the file is equal to (nFileSizeHigh* - * (MAXDWORD+1)) + nFileSizeLow. - */ - public int nFileIndexHigh; - /** - * The low-order DWORD value of the file size, in bytes. - */ - public int nFileIndexLow; + + //the native fields /** * The file attributes of a file. For possible values and their descriptions, see File Attribute Constants. The FILE_ATTRIBUTE_SPARSE_FILE attribute on the file is set if any * of the streams of the file have ever been sparse. */ public int dwFileAttributes; + /** * A FILETIME structure that specifies when a file or directory was created. If the underlying file system does not support creation time, this member is zero. */ - public FILETIME ftCreationTime; + /** * A FILETIME structure. For a file, the structure specifies when the file was last read from, written to, or for executable files, run. For a directory, the structure * specifies when the directory is created. If the underlying file system does not support last access time, this member is zero. On the FAT file system, the specified date for * both files and directories is correct, but the time of day is always set to midnight. */ - public FILETIME ftLastAccessTime; + /** * A FILETIME structure. For a file, the structure specifies when the file was last written to, truncated, or overwritten, for example, when WriteFile or SetEndOfFile are used. * The date and time are not updated when file attributes or security descriptors are changed. For a directory, the structure specifies when the directory is created. If the * underlying file system does not support last write time, this member is zero. */ - public FILETIME ftLastWriteTime; + + /** + * The serial number of the volume that contains a file. + */ + public int dwVolumeSerialNumber; + /** * The high-order DWORD value of the file size, in bytes. This value is zero unless the file size is greater than MAXDWORD. The size of the file is equal to (nFileSizeHigh * * (MAXDWORD+1)) + nFileSizeLow. @@ -78,9 +81,23 @@ public class ByHandleFileInfo extends Structure implements Structure.ByReference * The low-order DWORD value of the file size, in bytes. */ public int nFileSizeLow; - public int dwVolumeSerialNumber; + + /** + * The number of links to this file. For the FAT file system this member is always 1. For the NTFS file system, it can be more than 1. + */ public int dwNumberOfLinks = 1; + /** + * The high-order DWORD value of the file size, in bytes. This value is zero unless the file size is greater than MAXDWORD. The size of the file is equal to (nFileSizeHigh* + * (MAXDWORD+1)) + nFileSizeLow. + */ + public int nFileIndexHigh; + + /** + * The low-order DWORD value of the file size, in bytes. + */ + public int nFileIndexLow; + public ByHandleFileInfo(final FILETIME creationTime, final FILETIME lastAccessTime, final FILETIME lastWriteTime) { setTimes(creationTime, lastAccessTime, lastWriteTime); } @@ -163,17 +180,13 @@ public final long getSize() { } public void setIndex(final long indexToSet) { - if (indexToSet == 0) { - counter.getAndIncrement(); - } - setIndex(indexToSet, (int) (indexToSet >> 32), (int) indexToSet); + setIndex(indexToSet, (int) (indexToSet >>> 32), (int) ((indexToSet << 32) >>> 32)); } final void setIndex(final long index, final int indexHigh, final int indexLow) { this.fileIndex = index; - final WinNT.LARGE_INTEGER largeInt = new WinNT.LARGE_INTEGER(index); - this.nFileIndexHigh = largeInt.getHigh().intValue(); - this.nFileIndexLow = largeInt.getLow().intValue(); + this.nFileIndexHigh = indexHigh; + this.nFileIndexLow = indexLow; } @Override @@ -184,6 +197,6 @@ public List getFieldOrder() { @Override @SuppressWarnings("all") public String toString() { - return "ByHandleFileInfo(counter=" + this.counter + ", filePath=" + this.filePath + ", fileIndex=" + this.fileIndex + ", fileSize=" + this.fileSize + ", nFileIndexHigh=" + this.nFileIndexHigh + ", nFileIndexLow=" + this.nFileIndexLow + ", dwFileAttributes=" + this.dwFileAttributes + ", ftCreationTime=" + this.ftCreationTime + ", ftLastAccessTime=" + this.ftLastAccessTime + ", ftLastWriteTime=" + this.ftLastWriteTime + ", nFileSizeHigh=" + this.nFileSizeHigh + ", nFileSizeLow=" + this.nFileSizeLow + ", dwVolumeSerialNumber=" + this.dwVolumeSerialNumber + ", dwNumberOfLinks=" + this.dwNumberOfLinks + ")"; + return "ByHandleFileInfo(filePath=" + this.filePath + ", fileIndex=" + this.fileIndex + ", fileSize=" + this.fileSize + ", nFileIndexHigh=" + this.nFileIndexHigh + ", nFileIndexLow=" + this.nFileIndexLow + ", dwFileAttributes=" + this.dwFileAttributes + ", ftCreationTime=" + this.ftCreationTime + ", ftLastAccessTime=" + this.ftLastAccessTime + ", ftLastWriteTime=" + this.ftLastWriteTime + ", nFileSizeHigh=" + this.nFileSizeHigh + ", nFileSizeLow=" + this.nFileSizeLow + ", dwVolumeSerialNumber=" + this.dwVolumeSerialNumber + ", dwNumberOfLinks=" + this.dwNumberOfLinks + ")"; } } diff --git a/src/main/java/org/cryptomator/frontend/dokany/ReadWriteAdapter.java b/src/main/java/org/cryptomator/frontend/dokany/ReadWriteAdapter.java index e0705c5..93e47f7 100644 --- a/src/main/java/org/cryptomator/frontend/dokany/ReadWriteAdapter.java +++ b/src/main/java/org/cryptomator/frontend/dokany/ReadWriteAdapter.java @@ -51,7 +51,6 @@ import java.nio.file.attribute.DosFileAttributes; import java.nio.file.attribute.FileTime; import java.util.Collections; -import java.util.Date; import java.util.Objects; import java.util.Optional; import java.util.Set; @@ -469,7 +468,6 @@ public int getFileInformation(WString fileName, ByHandleFileInfo handleFileInfo, try (PathLock pathLock = lockManager.createPathLock(path.toString()).forReading(); DataLock dataLock = pathLock.lockDataForReading()) { DosFileAttributes attr = Files.readAttributes(path, DosFileAttributes.class, LinkOption.NOFOLLOW_LINKS); - LOG.trace("({}) Filesize of {} is {}.", dokanyFileInfo.Context, path, attr.size()); FullFileInfo data = toFullFileInfo(path, attr); data.copyTo(handleFileInfo); LOG.trace("({}) File Information successful read from {}.", dokanyFileInfo.Context, path); @@ -498,7 +496,6 @@ private FullFileInfo toFullFileInfo(Path path, DosFileAttributes attr) { DokanyUtils.getTime(attr.lastAccessTime().toMillis()), DokanyUtils.getTime(attr.lastModifiedTime().toMillis())); data.setSize(attr.size()); - LOG.trace("Timestamps for {}:\t mTime {} \t cTime {} \t aTime {}",path, data.ftLastWriteTime.toTime(), data.ftCreationTime.toTime(), data.ftLastAccessTime.toTime()); return data; } @@ -875,19 +872,6 @@ public int getFileSecurity(WString rawPath, int rawSecurityInformation, Pointer @Override public int setFileSecurity(WString rawPath, int rawSecurityInformation, Pointer rawSecurityDescriptor, int rawSecurityDescriptorLength, DokanyFileInfo dokanyFileInfo) { -// Path path = getRootedPath(rawPath); -// LOG.trace("setFileSecurity() is called for " + path.toString()); -// if (Files.exists(path)) { -// byte[] securityDescriptor = FileUtil.getStandardSecurityDescriptor(); -// if (securityDescriptor.length <= rawSecurityDescriptorLength) { -// rawSecurityDescriptor.write(0L, securityDescriptor, 0, securityDescriptor.length); -// return Win32ErrorCode.SUCCESS.getMask(); -// } else { -// return Win32ErrorCode.BUFFER_OVERFLOW.getMask(); -// } -// } else { -// return Win32ErrorCode.ERROR_FILE_NOT_FOUND.getMask(); -// } return 0; }