From d19587a34c467dbced5edb28490546a489bcd497 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Mon, 11 Jul 2022 10:52:37 +0200 Subject: [PATCH 01/21] reset version to snapshot [ci skip] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1971e34..c355652 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ 4.0.0 org.cryptomator integrations-win - 1.1.2 + 1.2.0-SNAPSHOT Cryptomator Integrations for Windows Provides optional Windows services used by Cryptomator From de29921875093acdd3f4d589d0547eed28e0d08f Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Mon, 11 Jul 2022 12:14:37 +0200 Subject: [PATCH 02/21] Add slack notification --- .github/workflows/publish-github.yml | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish-github.yml b/.github/workflows/publish-github.yml index a63d99b..79c80b2 100644 --- a/.github/workflows/publish-github.yml +++ b/.github/workflows/publish-github.yml @@ -26,4 +26,20 @@ jobs: run: mvn deploy -B -DskipTests -Psign,deploy-github --no-transfer-progress env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - MAVEN_GPG_PASSPHRASE: ${{ secrets.RELEASES_GPG_PASSPHRASE }} \ No newline at end of file + MAVEN_GPG_PASSPHRASE: ${{ secrets.RELEASES_GPG_PASSPHRASE }} + notify: + runs-on: ubuntu-latest + needs: [publish] + steps: + - 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 From c3e5aaf9d9e6d6f6c36af499e8badd38eacbfd7d Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Thu, 13 Oct 2022 17:14:40 +0200 Subject: [PATCH 03/21] bump versions of used gh actions --- .github/workflows/build.yml | 8 ++++---- .github/workflows/codeql-analysis.yml | 8 ++++---- .github/workflows/publish-central.yml | 4 ++-- .github/workflows/publish-github.yml | 4 ++-- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 227de96..f2a0c4f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -12,8 +12,8 @@ jobs: runs-on: windows-latest if: "!contains(github.event.head_commit.message, '[ci skip]') && !contains(github.event.head_commit.message, '[skip ci]')" steps: - - uses: actions/checkout@v2 - - uses: actions/setup-java@v2 + - uses: actions/checkout@v3 + - uses: actions/setup-java@v3 with: distribution: 'temurin' java-version: 17 @@ -25,12 +25,12 @@ jobs: - name: Build and Test id: buildAndTest run: mvn -B clean install -Pdependency-check - - uses: actions/upload-artifact@v2 + - uses: actions/upload-artifact@v3 with: name: artifacts path: target/*.jar - name: Create Release - uses: actions/create-release@v1 + uses: actions/create-release@v1 # NOTE: action is unmaintained and repo archived if: startsWith(github.ref, 'refs/tags/') env: GITHUB_TOKEN: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }} # release as "cryptobot" diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index ef97a85..ae1912a 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -19,19 +19,19 @@ jobs: runs-on: windows-2019 if: "!contains(github.event.head_commit.message, '[ci skip]') && !contains(github.event.head_commit.message, '[skip ci]')" steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 2 - - uses: actions/setup-java@v2 + - uses: actions/setup-java@v3 with: distribution: 'temurin' java-version: 17 cache: 'maven' - name: Initialize CodeQL - uses: github/codeql-action/init@v1 + uses: github/codeql-action/init@v2 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 + uses: github/codeql-action/analyze@v2 \ No newline at end of file diff --git a/.github/workflows/publish-central.yml b/.github/workflows/publish-central.yml index 747dc38..150b20c 100644 --- a/.github/workflows/publish-central.yml +++ b/.github/workflows/publish-central.yml @@ -15,10 +15,10 @@ jobs: publish: runs-on: windows-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: ref: "refs/tags/${{ github.event.inputs.tag }}" - - uses: actions/setup-java@v2 + - uses: actions/setup-java@v3 with: distribution: 'temurin' java-version: 17 diff --git a/.github/workflows/publish-github.yml b/.github/workflows/publish-github.yml index 79c80b2..a24a7bb 100644 --- a/.github/workflows/publish-github.yml +++ b/.github/workflows/publish-github.yml @@ -12,8 +12,8 @@ jobs: runs-on: windows-latest if: startsWith(github.ref, 'refs/tags/') # only allow publishing tagged versions steps: - - uses: actions/checkout@v2 - - uses: actions/setup-java@v2 + - uses: actions/checkout@v3 + - uses: actions/setup-java@v3 with: distribution: 'temurin' java-version: 17 From 479d8518e18abdc79fde94c09d7e3a492b9e863f Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Sun, 8 Jan 2023 19:36:47 +0100 Subject: [PATCH 04/21] bump api version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c355652..4d67693 100644 --- a/pom.xml +++ b/pom.xml @@ -37,7 +37,7 @@ 17 - 1.1.0 + 1.2.0-SNAPSHOT 1.7.36 2.9.0 From 629777480c2612bf58b55a5306303edfbee707fe Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Sun, 8 Jan 2023 19:38:11 +0100 Subject: [PATCH 05/21] move method to convert to windows strings to common package --- .../windows/autostart/WinShellLinks.java | 16 ++++---------- .../windows/common/WinStrings.java | 14 ++++++++++++ .../windows/autostart/WinShellLinksTest.java | 12 ---------- .../windows/common/WinStringsTest.java | 22 +++++++++++++++++++ 4 files changed, 40 insertions(+), 24 deletions(-) create mode 100644 src/main/java/org/cryptomator/windows/common/WinStrings.java create mode 100644 src/test/java/org/cryptomator/windows/common/WinStringsTest.java diff --git a/src/main/java/org/cryptomator/windows/autostart/WinShellLinks.java b/src/main/java/org/cryptomator/windows/autostart/WinShellLinks.java index 39caa91..25a2a5e 100644 --- a/src/main/java/org/cryptomator/windows/autostart/WinShellLinks.java +++ b/src/main/java/org/cryptomator/windows/autostart/WinShellLinks.java @@ -1,9 +1,7 @@ package org.cryptomator.windows.autostart; import org.cryptomator.windows.common.NativeLibLoader; - -import java.nio.charset.StandardCharsets; -import java.util.Arrays; +import org.cryptomator.windows.common.WinStrings; /** * Interface to the native Windows shell link interface. @@ -22,18 +20,12 @@ public class WinShellLinks { */ public int createShortcut(String target, String storagePath, String description) { return Native.INSTANCE.createShortcut( - getNullTerminatedUTF16Representation(target), - getNullTerminatedUTF16Representation(storagePath), - getNullTerminatedUTF16Representation(description) + WinStrings.getNullTerminatedUTF16Representation(target), + WinStrings.getNullTerminatedUTF16Representation(storagePath), + WinStrings.getNullTerminatedUTF16Representation(description) ); } - // visible for testing - byte[] getNullTerminatedUTF16Representation(String source) { - byte[] bytes = source.getBytes(StandardCharsets.UTF_16LE); - return Arrays.copyOf(bytes, bytes.length + 2); // add double-width null terminator 0x00 0x00 - } - private static class Native { static final Native INSTANCE = new Native(); diff --git a/src/main/java/org/cryptomator/windows/common/WinStrings.java b/src/main/java/org/cryptomator/windows/common/WinStrings.java new file mode 100644 index 0000000..6d8cb5a --- /dev/null +++ b/src/main/java/org/cryptomator/windows/common/WinStrings.java @@ -0,0 +1,14 @@ +package org.cryptomator.windows.common; + +import java.nio.charset.StandardCharsets; +import java.util.Arrays; + +public class WinStrings { + + private WinStrings() {} + + public static byte[] getNullTerminatedUTF16Representation(String source) { + byte[] bytes = source.getBytes(StandardCharsets.UTF_16LE); + return Arrays.copyOf(bytes, bytes.length + 2); // add double-width null terminator 0x00 0x00 + } +} diff --git a/src/test/java/org/cryptomator/windows/autostart/WinShellLinksTest.java b/src/test/java/org/cryptomator/windows/autostart/WinShellLinksTest.java index 661fe6a..7761847 100644 --- a/src/test/java/org/cryptomator/windows/autostart/WinShellLinksTest.java +++ b/src/test/java/org/cryptomator/windows/autostart/WinShellLinksTest.java @@ -40,18 +40,6 @@ public void testShellLinkCreation() { Assertions.assertTrue(Files.exists(shortcut)); } - @ParameterizedTest - @CsvSource(value = { // convert utf16-le string to hex with https://dencode.com/en/string/hex, append null terminator - "foo, '66 00 6f 00 6f 00 00 00'", - "bar, '62 00 61 00 72 00 00 00'" - }) - public void testGetNullTerminatedUTF16Representation(String input, @ConvertWith(ByteArrayConverter.class) byte[] expected) { - WinShellLinks winShellLinks = new WinShellLinks(); - - var result = winShellLinks.getNullTerminatedUTF16Representation(input); - - Assertions.assertArrayEquals(expected, result); - } @ParameterizedTest @CsvSource(value = { diff --git a/src/test/java/org/cryptomator/windows/common/WinStringsTest.java b/src/test/java/org/cryptomator/windows/common/WinStringsTest.java new file mode 100644 index 0000000..3de0263 --- /dev/null +++ b/src/test/java/org/cryptomator/windows/common/WinStringsTest.java @@ -0,0 +1,22 @@ +package org.cryptomator.windows.common; + +import org.cryptomator.windows.autostart.WinShellLinksTest; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.converter.ConvertWith; +import org.junit.jupiter.params.provider.CsvSource; + +public class WinStringsTest { + + + @ParameterizedTest + @CsvSource(value = { // convert utf16-le string to hex with https://dencode.com/en/string/hex, append null terminator + "foo, '66 00 6f 00 6f 00 00 00'", + "bar, '62 00 61 00 72 00 00 00'" + }) + public void testGetNullTerminatedUTF16Representation(String input, @ConvertWith(WinShellLinksTest.ByteArrayConverter.class) byte[] expected) { + var result = WinStrings.getNullTerminatedUTF16Representation(input); + + Assertions.assertArrayEquals(expected, result); + } +} From 06e774a2b410df52454fa992899ebb9fb1a476f8 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Tue, 10 Jan 2023 14:24:56 +0100 Subject: [PATCH 06/21] implement reveal path service via explorer command --- src/main/java/module-info.java | 3 ++ .../ExplorerRevealPathsService.java | 50 +++++++++++++++++++ .../ExplorerRevealPathsServiceTest.java | 24 +++++++++ 3 files changed, 77 insertions(+) create mode 100644 src/main/java/org/cryptomator/windows/revealpaths/ExplorerRevealPathsService.java create mode 100644 src/test/java/org/cryptomator/windows/revealpaths/ExplorerRevealPathsServiceTest.java diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 6a58be8..01e9311 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -1,8 +1,10 @@ import org.cryptomator.integrations.autostart.AutoStartProvider; import org.cryptomator.integrations.keychain.KeychainAccessProvider; +import org.cryptomator.integrations.revealpaths.RevealPathsService; import org.cryptomator.integrations.uiappearance.UiAppearanceProvider; import org.cryptomator.windows.autostart.WindowsAutoStart; import org.cryptomator.windows.keychain.WindowsProtectedKeychainAccess; +import org.cryptomator.windows.revealpaths.ExplorerRevealPathsService; import org.cryptomator.windows.uiappearance.WinUiAppearanceProvider; module org.cryptomator.integrations.win { @@ -15,4 +17,5 @@ provides AutoStartProvider with WindowsAutoStart; provides KeychainAccessProvider with WindowsProtectedKeychainAccess; provides UiAppearanceProvider with WinUiAppearanceProvider; + provides RevealPathsService with ExplorerRevealPathsService; } \ No newline at end of file diff --git a/src/main/java/org/cryptomator/windows/revealpaths/ExplorerRevealPathsService.java b/src/main/java/org/cryptomator/windows/revealpaths/ExplorerRevealPathsService.java new file mode 100644 index 0000000..0aa9798 --- /dev/null +++ b/src/main/java/org/cryptomator/windows/revealpaths/ExplorerRevealPathsService.java @@ -0,0 +1,50 @@ +package org.cryptomator.windows.revealpaths; + +import org.cryptomator.integrations.common.OperatingSystem; +import org.cryptomator.integrations.common.Priority; +import org.cryptomator.integrations.revealpaths.RevealFailedException; +import org.cryptomator.integrations.revealpaths.RevealPathsService; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.NoSuchFileException; +import java.nio.file.Path; +import java.util.concurrent.TimeUnit; + +@Priority(100) +@OperatingSystem(OperatingSystem.Value.WINDOWS) +public class ExplorerRevealPathsService implements RevealPathsService { + + @Override + public void reveal(Path p) throws RevealFailedException, NoSuchFileException { + if(!Files.exists(p)) { + throw new NoSuchFileException("File cannot be found: "+p.toString()); + } + ProcessBuilder pb = new ProcessBuilder() + .command("explorer", "/select,\"" + p.toString() + "\""); + try { + var process = pb.start(); + if (process.waitFor(5000, TimeUnit.MILLISECONDS)) { + int exitValue = process.exitValue(); + if (process.exitValue() != 1) { //explorer.exe seems to return always 1 + throw new RevealFailedException("Explorer.exe exited with value " + exitValue); + } + } + } catch (IOException e) { + throw new RevealFailedException(e); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new RevealFailedException(e); + } + } + + @Override + public String displayName() { + return "Windows Explorer"; + } + + @Override + public boolean isSupported() { + return true; + } +} diff --git a/src/test/java/org/cryptomator/windows/revealpaths/ExplorerRevealPathsServiceTest.java b/src/test/java/org/cryptomator/windows/revealpaths/ExplorerRevealPathsServiceTest.java new file mode 100644 index 0000000..7a064cf --- /dev/null +++ b/src/test/java/org/cryptomator/windows/revealpaths/ExplorerRevealPathsServiceTest.java @@ -0,0 +1,24 @@ +package org.cryptomator.windows.revealpaths; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + +public class ExplorerRevealPathsServiceTest { + + ExplorerRevealPathsService service = new ExplorerRevealPathsService(); + + @Test + public void testReveal(@TempDir Path tmpDir) throws IOException { + Path foo = tmpDir.resolve("foo.txt"); + + Files.createFile(foo); + + Assertions.assertDoesNotThrow(() -> service.reveal(foo)); + Assertions.assertTrue(Files.exists(foo)); + } +} From 637331655aa9489f706a9cd24eba5be0d3977888 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Wed, 11 Jan 2023 11:32:52 +0100 Subject: [PATCH 07/21] Adjust explorer reveal service to final api spec --- pom.xml | 2 +- src/main/java/module-info.java | 6 ++--- .../ExplorerRevealPathService.java} | 26 +++++++------------ .../ExplorerRevealPathServiceTest.java} | 14 +++++++--- 4 files changed, 25 insertions(+), 23 deletions(-) rename src/main/java/org/cryptomator/windows/{revealpaths/ExplorerRevealPathsService.java => revealpath/ExplorerRevealPathService.java} (56%) rename src/test/java/org/cryptomator/windows/{revealpaths/ExplorerRevealPathsServiceTest.java => revealpath/ExplorerRevealPathServiceTest.java} (52%) diff --git a/pom.xml b/pom.xml index 4d67693..333c4d4 100644 --- a/pom.xml +++ b/pom.xml @@ -37,7 +37,7 @@ 17 - 1.2.0-SNAPSHOT + 1.2.0-beta4 1.7.36 2.9.0 diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 01e9311..1e6e53a 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -1,10 +1,10 @@ import org.cryptomator.integrations.autostart.AutoStartProvider; import org.cryptomator.integrations.keychain.KeychainAccessProvider; -import org.cryptomator.integrations.revealpaths.RevealPathsService; +import org.cryptomator.integrations.revealpath.RevealPathService; import org.cryptomator.integrations.uiappearance.UiAppearanceProvider; import org.cryptomator.windows.autostart.WindowsAutoStart; import org.cryptomator.windows.keychain.WindowsProtectedKeychainAccess; -import org.cryptomator.windows.revealpaths.ExplorerRevealPathsService; +import org.cryptomator.windows.revealpath.ExplorerRevealPathService; import org.cryptomator.windows.uiappearance.WinUiAppearanceProvider; module org.cryptomator.integrations.win { @@ -17,5 +17,5 @@ provides AutoStartProvider with WindowsAutoStart; provides KeychainAccessProvider with WindowsProtectedKeychainAccess; provides UiAppearanceProvider with WinUiAppearanceProvider; - provides RevealPathsService with ExplorerRevealPathsService; + provides RevealPathService with ExplorerRevealPathService; } \ No newline at end of file diff --git a/src/main/java/org/cryptomator/windows/revealpaths/ExplorerRevealPathsService.java b/src/main/java/org/cryptomator/windows/revealpath/ExplorerRevealPathService.java similarity index 56% rename from src/main/java/org/cryptomator/windows/revealpaths/ExplorerRevealPathsService.java rename to src/main/java/org/cryptomator/windows/revealpath/ExplorerRevealPathService.java index 0aa9798..46ce395 100644 --- a/src/main/java/org/cryptomator/windows/revealpaths/ExplorerRevealPathsService.java +++ b/src/main/java/org/cryptomator/windows/revealpath/ExplorerRevealPathService.java @@ -1,28 +1,27 @@ -package org.cryptomator.windows.revealpaths; +package org.cryptomator.windows.revealpath; import org.cryptomator.integrations.common.OperatingSystem; import org.cryptomator.integrations.common.Priority; -import org.cryptomator.integrations.revealpaths.RevealFailedException; -import org.cryptomator.integrations.revealpaths.RevealPathsService; +import org.cryptomator.integrations.revealpath.RevealFailedException; +import org.cryptomator.integrations.revealpath.RevealPathService; import java.io.IOException; import java.nio.file.Files; -import java.nio.file.NoSuchFileException; +import java.nio.file.LinkOption; import java.nio.file.Path; +import java.nio.file.attribute.BasicFileAttributes; import java.util.concurrent.TimeUnit; @Priority(100) @OperatingSystem(OperatingSystem.Value.WINDOWS) -public class ExplorerRevealPathsService implements RevealPathsService { +public class ExplorerRevealPathService implements RevealPathService { @Override - public void reveal(Path p) throws RevealFailedException, NoSuchFileException { - if(!Files.exists(p)) { - throw new NoSuchFileException("File cannot be found: "+p.toString()); - } - ProcessBuilder pb = new ProcessBuilder() - .command("explorer", "/select,\"" + p.toString() + "\""); + public void reveal(Path p) throws RevealFailedException { try { + var attrs = Files.readAttributes(p, BasicFileAttributes.class, LinkOption.NOFOLLOW_LINKS); + var args = (attrs.isDirectory() ? "" : "/select,") + "\"" + p.toString() + "\""; + ProcessBuilder pb = new ProcessBuilder().command("explorer", args); var process = pb.start(); if (process.waitFor(5000, TimeUnit.MILLISECONDS)) { int exitValue = process.exitValue(); @@ -38,11 +37,6 @@ public void reveal(Path p) throws RevealFailedException, NoSuchFileException { } } - @Override - public String displayName() { - return "Windows Explorer"; - } - @Override public boolean isSupported() { return true; diff --git a/src/test/java/org/cryptomator/windows/revealpaths/ExplorerRevealPathsServiceTest.java b/src/test/java/org/cryptomator/windows/revealpath/ExplorerRevealPathServiceTest.java similarity index 52% rename from src/test/java/org/cryptomator/windows/revealpaths/ExplorerRevealPathsServiceTest.java rename to src/test/java/org/cryptomator/windows/revealpath/ExplorerRevealPathServiceTest.java index 7a064cf..f70e7b7 100644 --- a/src/test/java/org/cryptomator/windows/revealpaths/ExplorerRevealPathsServiceTest.java +++ b/src/test/java/org/cryptomator/windows/revealpath/ExplorerRevealPathServiceTest.java @@ -1,5 +1,6 @@ -package org.cryptomator.windows.revealpaths; +package org.cryptomator.windows.revealpath; +import org.cryptomator.integrations.revealpath.RevealFailedException; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; @@ -8,9 +9,9 @@ import java.nio.file.Files; import java.nio.file.Path; -public class ExplorerRevealPathsServiceTest { +public class ExplorerRevealPathServiceTest { - ExplorerRevealPathsService service = new ExplorerRevealPathsService(); + ExplorerRevealPathService service = new ExplorerRevealPathService(); @Test public void testReveal(@TempDir Path tmpDir) throws IOException { @@ -21,4 +22,11 @@ public void testReveal(@TempDir Path tmpDir) throws IOException { Assertions.assertDoesNotThrow(() -> service.reveal(foo)); Assertions.assertTrue(Files.exists(foo)); } + + @Test + public void testRevealFailed(@TempDir Path tmpDir) { + Path foo = tmpDir.resolve("bar.txt"); + + Assertions.assertThrows(RevealFailedException.class, () -> service.reveal(foo)); + } } From e949f4072fe3e3299d966ebff4f47c7316de1f05 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Wed, 11 Jan 2023 16:58:11 +0100 Subject: [PATCH 08/21] Revert "move method to convert to windows strings to common package" This reverts commit 629777480c2612bf58b55a5306303edfbee707fe. --- .../windows/autostart/WinShellLinks.java | 16 ++++++++++---- .../windows/common/WinStrings.java | 14 ------------ .../windows/autostart/WinShellLinksTest.java | 12 ++++++++++ .../windows/common/WinStringsTest.java | 22 ------------------- 4 files changed, 24 insertions(+), 40 deletions(-) delete mode 100644 src/main/java/org/cryptomator/windows/common/WinStrings.java delete mode 100644 src/test/java/org/cryptomator/windows/common/WinStringsTest.java diff --git a/src/main/java/org/cryptomator/windows/autostart/WinShellLinks.java b/src/main/java/org/cryptomator/windows/autostart/WinShellLinks.java index 25a2a5e..39caa91 100644 --- a/src/main/java/org/cryptomator/windows/autostart/WinShellLinks.java +++ b/src/main/java/org/cryptomator/windows/autostart/WinShellLinks.java @@ -1,7 +1,9 @@ package org.cryptomator.windows.autostart; import org.cryptomator.windows.common.NativeLibLoader; -import org.cryptomator.windows.common.WinStrings; + +import java.nio.charset.StandardCharsets; +import java.util.Arrays; /** * Interface to the native Windows shell link interface. @@ -20,12 +22,18 @@ public class WinShellLinks { */ public int createShortcut(String target, String storagePath, String description) { return Native.INSTANCE.createShortcut( - WinStrings.getNullTerminatedUTF16Representation(target), - WinStrings.getNullTerminatedUTF16Representation(storagePath), - WinStrings.getNullTerminatedUTF16Representation(description) + getNullTerminatedUTF16Representation(target), + getNullTerminatedUTF16Representation(storagePath), + getNullTerminatedUTF16Representation(description) ); } + // visible for testing + byte[] getNullTerminatedUTF16Representation(String source) { + byte[] bytes = source.getBytes(StandardCharsets.UTF_16LE); + return Arrays.copyOf(bytes, bytes.length + 2); // add double-width null terminator 0x00 0x00 + } + private static class Native { static final Native INSTANCE = new Native(); diff --git a/src/main/java/org/cryptomator/windows/common/WinStrings.java b/src/main/java/org/cryptomator/windows/common/WinStrings.java deleted file mode 100644 index 6d8cb5a..0000000 --- a/src/main/java/org/cryptomator/windows/common/WinStrings.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.cryptomator.windows.common; - -import java.nio.charset.StandardCharsets; -import java.util.Arrays; - -public class WinStrings { - - private WinStrings() {} - - public static byte[] getNullTerminatedUTF16Representation(String source) { - byte[] bytes = source.getBytes(StandardCharsets.UTF_16LE); - return Arrays.copyOf(bytes, bytes.length + 2); // add double-width null terminator 0x00 0x00 - } -} diff --git a/src/test/java/org/cryptomator/windows/autostart/WinShellLinksTest.java b/src/test/java/org/cryptomator/windows/autostart/WinShellLinksTest.java index 7761847..661fe6a 100644 --- a/src/test/java/org/cryptomator/windows/autostart/WinShellLinksTest.java +++ b/src/test/java/org/cryptomator/windows/autostart/WinShellLinksTest.java @@ -40,6 +40,18 @@ public void testShellLinkCreation() { Assertions.assertTrue(Files.exists(shortcut)); } + @ParameterizedTest + @CsvSource(value = { // convert utf16-le string to hex with https://dencode.com/en/string/hex, append null terminator + "foo, '66 00 6f 00 6f 00 00 00'", + "bar, '62 00 61 00 72 00 00 00'" + }) + public void testGetNullTerminatedUTF16Representation(String input, @ConvertWith(ByteArrayConverter.class) byte[] expected) { + WinShellLinks winShellLinks = new WinShellLinks(); + + var result = winShellLinks.getNullTerminatedUTF16Representation(input); + + Assertions.assertArrayEquals(expected, result); + } @ParameterizedTest @CsvSource(value = { diff --git a/src/test/java/org/cryptomator/windows/common/WinStringsTest.java b/src/test/java/org/cryptomator/windows/common/WinStringsTest.java deleted file mode 100644 index 3de0263..0000000 --- a/src/test/java/org/cryptomator/windows/common/WinStringsTest.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.cryptomator.windows.common; - -import org.cryptomator.windows.autostart.WinShellLinksTest; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.converter.ConvertWith; -import org.junit.jupiter.params.provider.CsvSource; - -public class WinStringsTest { - - - @ParameterizedTest - @CsvSource(value = { // convert utf16-le string to hex with https://dencode.com/en/string/hex, append null terminator - "foo, '66 00 6f 00 6f 00 00 00'", - "bar, '62 00 61 00 72 00 00 00'" - }) - public void testGetNullTerminatedUTF16Representation(String input, @ConvertWith(WinShellLinksTest.ByteArrayConverter.class) byte[] expected) { - var result = WinStrings.getNullTerminatedUTF16Representation(input); - - Assertions.assertArrayEquals(expected, result); - } -} From 7e773ca23ca62df2529adbbd0d948f374afca532 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Sat, 14 Jan 2023 00:04:33 +0100 Subject: [PATCH 09/21] use windows predefined startup folder --- ...r_windows_autostart_WinShellLinks_Native.h | 8 +++++ .../windows/autostart/WinShellLinks.java | 15 ++++++-- .../windows/autostart/WindowsAutoStart.java | 21 ++++++------ ...windows_autostart_WinShellLinks_Native.cpp | 34 +++++++++++++++++-- .../windows/autostart/WinShellLinksTest.java | 6 ++++ 5 files changed, 69 insertions(+), 15 deletions(-) diff --git a/src/main/headers/org_cryptomator_windows_autostart_WinShellLinks_Native.h b/src/main/headers/org_cryptomator_windows_autostart_WinShellLinks_Native.h index 43e59bc..fe26551 100644 --- a/src/main/headers/org_cryptomator_windows_autostart_WinShellLinks_Native.h +++ b/src/main/headers/org_cryptomator_windows_autostart_WinShellLinks_Native.h @@ -15,6 +15,14 @@ extern "C" { JNIEXPORT jint JNICALL Java_org_cryptomator_windows_autostart_WinShellLinks_00024Native_createShortcut (JNIEnv *, jobject, jbyteArray, jbyteArray, jbyteArray); +/* + * Class: org_cryptomator_windows_autostart_WinShellLinks_Native + * Method: createAndGetStartupFolderPath + * Signature: ()Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_cryptomator_windows_autostart_WinShellLinks_00024Native_createAndGetStartupFolderPath + (JNIEnv *, jobject); + #ifdef __cplusplus } #endif diff --git a/src/main/java/org/cryptomator/windows/autostart/WinShellLinks.java b/src/main/java/org/cryptomator/windows/autostart/WinShellLinks.java index 39caa91..ba0b86a 100644 --- a/src/main/java/org/cryptomator/windows/autostart/WinShellLinks.java +++ b/src/main/java/org/cryptomator/windows/autostart/WinShellLinks.java @@ -15,7 +15,7 @@ public class WinShellLinks { /** * Create a Windows shortcut file to the given target, at the specified location and with a description. * - * @param target path of the target the shortcut points to + * @param target path of the target the shortcut points to * @param storagePath path where the shortcut is created * @param description string inserted in the description field of the shortcut. * @return {@code 0} if everything worked, otherwise an HRESULT error code @@ -28,6 +28,15 @@ public int createShortcut(String target, String storagePath, String description) ); } + /** + * Gets the file system path of the startup folder. Creates all directories in the path, if necessary. + * + * @return path to the startup folder with no trailing \ or {@code null}, if the folder is not defined or cannot be created + */ + public String getPathToStartupFolder() { + return Native.INSTANCE.createAndGetStartupFolderPath(); + } + // visible for testing byte[] getNullTerminatedUTF16Representation(String source) { byte[] bytes = source.getBytes(StandardCharsets.UTF_16LE); @@ -41,6 +50,8 @@ private Native() { NativeLibLoader.loadLib(); } - public synchronized native int createShortcut(byte[] target, byte[] storagePath, byte[] description); + synchronized native int createShortcut(byte[] target, byte[] storagePath, byte[] description); + + native String createAndGetStartupFolderPath(); } } diff --git a/src/main/java/org/cryptomator/windows/autostart/WindowsAutoStart.java b/src/main/java/org/cryptomator/windows/autostart/WindowsAutoStart.java index 411c394..381fa35 100644 --- a/src/main/java/org/cryptomator/windows/autostart/WindowsAutoStart.java +++ b/src/main/java/org/cryptomator/windows/autostart/WindowsAutoStart.java @@ -17,7 +17,7 @@ /** * Checks, en- and disables autostart for an application on Windows using the startup folder. *

- * The above actions are done by checking/adding/removing in the directory {@value RELATIVE_STARTUP_FOLDER} a shell link (.lnk). + * The above actions are done by checking/adding/removing a shell link (.lnk) in the Windows defined Startup directory (see also https://learn.microsoft.com/en-us/windows/win32/shell/knownfolderid#constants). * The filename of the shell link is given by the JVM property {@value LNK_NAME_PROPERTY}. If the property is not set before object creation, the start command of the calling process is used. */ @Priority(1000) @@ -25,13 +25,12 @@ public class WindowsAutoStart implements AutoStartProvider { private static final Logger LOG = LoggerFactory.getLogger(WindowsAutoStart.class); - private static final String RELATIVE_STARTUP_FOLDER = "AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\"; private static final String LNK_FILE_EXTENSION = ".lnk"; private static final String LNK_NAME_PROPERTY = "cryptomator.integrationsWin.autoStartShellLinkName"; private final WinShellLinks winShellLinks; private final Optional shellLinkName; - private final Optional absStartupEntryPath; + private final Optional absShellLinkPath; private final Optional exePath; @SuppressWarnings("unused") // default constructor required by ServiceLoader @@ -39,12 +38,12 @@ public WindowsAutoStart() { this.winShellLinks = new WinShellLinks(); this.exePath = ProcessHandle.current().info().command().map(Path::of); this.shellLinkName = Optional.ofNullable(System.getProperty(LNK_NAME_PROPERTY)).or(() -> exePath.map(this::getExeBaseName)); - this.absStartupEntryPath = shellLinkName.map(name -> Path.of(System.getProperty("user.home"), RELATIVE_STARTUP_FOLDER, name + LNK_FILE_EXTENSION).toAbsolutePath()); + this.absShellLinkPath = Optional.ofNullable(winShellLinks.getPathToStartupFolder()).flatMap(p -> shellLinkName.map(name -> p + "\\" + name + LNK_FILE_EXTENSION)).map(Path::of); } @Override public boolean isEnabled() { - return absStartupEntryPath.map(Files::exists).orElse(false); + return absShellLinkPath.map(Files::exists).orElse(false); } @Override @@ -53,10 +52,10 @@ public synchronized void enable() throws ToggleAutoStartFailedException { throw new ToggleAutoStartFailedException("Enabling autostart using the startup folder failed: Path to executable is not set"); } - assert exePath.isPresent() && absStartupEntryPath.isPresent() && shellLinkName.isPresent(); - int returnCode = winShellLinks.createShortcut(exePath.get().toString(), absStartupEntryPath.get().toString(), shellLinkName.get()); + assert exePath.isPresent() && absShellLinkPath.isPresent() && shellLinkName.isPresent(); + int returnCode = winShellLinks.createShortcut(exePath.get().toString(), absShellLinkPath.get().toString(), shellLinkName.get()); if (returnCode == 0) { - LOG.debug("Successfully created {}.", absStartupEntryPath.get()); + LOG.debug("Successfully created {}.", absShellLinkPath.get()); } else { throw new ToggleAutoStartFailedException("Enabling autostart using the startup folder failed. Windows error code: " + Integer.toHexString(returnCode)); } @@ -65,13 +64,13 @@ public synchronized void enable() throws ToggleAutoStartFailedException { @Override public synchronized void disable() throws ToggleAutoStartFailedException { try { - Files.delete(absStartupEntryPath.get()); - LOG.debug("Successfully deleted {}.", absStartupEntryPath.get()); + Files.delete(absShellLinkPath.get()); + LOG.debug("Successfully deleted {}.", absShellLinkPath.get()); } catch (NoSuchElementException e) { //thrown by Optional::get throw new ToggleAutoStartFailedException("Disabling auto start failed using startup folder: Name of shell link is not defined."); } catch (NoSuchFileException e) { //also okay - LOG.debug("File {} not present. Nothing to do.", absStartupEntryPath.get()); + LOG.debug("File {} not present. Nothing to do.", absShellLinkPath.get()); } catch (IOException e) { LOG.debug("Failed to delete entry from auto start folder.", e); throw new ToggleAutoStartFailedException("Disabling auto start failed using startup folder.", e); diff --git a/src/main/native/org_cryptomator_windows_autostart_WinShellLinks_Native.cpp b/src/main/native/org_cryptomator_windows_autostart_WinShellLinks_Native.cpp index 663c5db..98e1f85 100644 --- a/src/main/native/org_cryptomator_windows_autostart_WinShellLinks_Native.cpp +++ b/src/main/native/org_cryptomator_windows_autostart_WinShellLinks_Native.cpp @@ -5,6 +5,8 @@ #include #include #include +#include +#include #include #include #include @@ -12,6 +14,33 @@ #include "org_cryptomator_windows_autostart_WinShellLinks_Native.h" HRESULT CreateLink(LPCWSTR lpszPathObj, LPCWSTR lpszPathLink, LPCWSTR lpszDesc); +//GUID of the Startup Folder: {B97D20BB-F46A-4C97-BA10-5E3608430854} +const GUID StartupFolderGUID = { + 0xB97D20BBu,0xF46Au,0x4C97u, 0xBAu, 0x10u, 0x5Eu,0x36u, 0x08u, 0x43u, 0x08u, 0x54u +}; + + +JNIEXPORT jstring JNICALL Java_org_cryptomator_windows_autostart_WinShellLinks_00024Native_createAndGetStartupFolderPath + (JNIEnv * env, jobject thisObj) { + + HRESULT hres; + PWSTR startupfolder_path; + hres = SHGetKnownFolderPath(StartupFolderGUID, KF_FLAG_CREATE | KF_FLAG_INIT, NULL, &startupfolder_path); //returns C:\Home, not C:\Home\ (NO trailing slash) + if(FAILED(hres)) { + return NULL; + } + + size_t length_startupfolder_path; + hres = StringCbLengthW(startupfolder_path, STRSAFE_MAX_CCH * sizeof(TCHAR), &length_startupfolder_path); + if(FAILED(hres)) { + CoTaskMemFree(startupfolder_path); + return NULL; + } + jstring s = env->NewString( (jchar *) startupfolder_path, length_startupfolder_path/sizeof(WCHAR) ); + CoTaskMemFree(startupfolder_path); + return s; +}; + JNIEXPORT jint JNICALL Java_org_cryptomator_windows_autostart_WinShellLinks_00024Native_createShortcut (JNIEnv * env, jobject thisObj, jbyteArray target, jbyteArray storage_path, jbyteArray description) { @@ -42,6 +71,7 @@ JNIEXPORT jint JNICALL Java_org_cryptomator_windows_autostart_WinShellLinks_0002 return hres; } + // CreateLink - Uses the Shell's IShellLink and IPersistFile interfaces // to create and store a shortcut to the specified object. // @@ -87,5 +117,5 @@ HRESULT CreateLink(LPCWSTR lpszPathObj, LPCWSTR lpszPathLink, LPCWSTR lpszDesc) } psl->Release(); } -return hres; -} + return hres; +} \ No newline at end of file diff --git a/src/test/java/org/cryptomator/windows/autostart/WinShellLinksTest.java b/src/test/java/org/cryptomator/windows/autostart/WinShellLinksTest.java index 661fe6a..01c9c14 100644 --- a/src/test/java/org/cryptomator/windows/autostart/WinShellLinksTest.java +++ b/src/test/java/org/cryptomator/windows/autostart/WinShellLinksTest.java @@ -29,6 +29,12 @@ public void setup(@TempDir Path tempDir) throws IOException { Files.createFile(linkTarget); } + @Test + public void testGetStartupFolderPath() { + WinShellLinks winShellLinks = new WinShellLinks(); + Assertions.assertDoesNotThrow(() -> winShellLinks.getPathToStartupFolder()); + } + @Test public void testShellLinkCreation() { WinShellLinks winShellLinks = new WinShellLinks(); From 295a569b8695379bab724273cc9a6a3df16c12e2 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Sat, 14 Jan 2023 00:21:31 +0100 Subject: [PATCH 10/21] improve code --- ...omator_windows_autostart_WinShellLinks_Native.cpp | 11 +++++------ .../windows/autostart/WinShellLinksTest.java | 12 +++++------- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/main/native/org_cryptomator_windows_autostart_WinShellLinks_Native.cpp b/src/main/native/org_cryptomator_windows_autostart_WinShellLinks_Native.cpp index 98e1f85..504f3ff 100644 --- a/src/main/native/org_cryptomator_windows_autostart_WinShellLinks_Native.cpp +++ b/src/main/native/org_cryptomator_windows_autostart_WinShellLinks_Native.cpp @@ -22,8 +22,9 @@ const GUID StartupFolderGUID = { JNIEXPORT jstring JNICALL Java_org_cryptomator_windows_autostart_WinShellLinks_00024Native_createAndGetStartupFolderPath (JNIEnv * env, jobject thisObj) { - HRESULT hres; + jstring result = NULL; + PWSTR startupfolder_path; hres = SHGetKnownFolderPath(StartupFolderGUID, KF_FLAG_CREATE | KF_FLAG_INIT, NULL, &startupfolder_path); //returns C:\Home, not C:\Home\ (NO trailing slash) if(FAILED(hres)) { @@ -32,13 +33,11 @@ JNIEXPORT jstring JNICALL Java_org_cryptomator_windows_autostart_WinShellLinks_0 size_t length_startupfolder_path; hres = StringCbLengthW(startupfolder_path, STRSAFE_MAX_CCH * sizeof(TCHAR), &length_startupfolder_path); - if(FAILED(hres)) { - CoTaskMemFree(startupfolder_path); - return NULL; + if(SUCCEEDED(hres)) { + result = env->NewString( (jchar *) startupfolder_path, length_startupfolder_path/sizeof(WCHAR) ); } - jstring s = env->NewString( (jchar *) startupfolder_path, length_startupfolder_path/sizeof(WCHAR) ); CoTaskMemFree(startupfolder_path); - return s; + return result; }; diff --git a/src/test/java/org/cryptomator/windows/autostart/WinShellLinksTest.java b/src/test/java/org/cryptomator/windows/autostart/WinShellLinksTest.java index 01c9c14..f0a4b1d 100644 --- a/src/test/java/org/cryptomator/windows/autostart/WinShellLinksTest.java +++ b/src/test/java/org/cryptomator/windows/autostart/WinShellLinksTest.java @@ -23,6 +23,8 @@ public class WinShellLinksTest { private Path linkTarget; private Path shortcut; + private WinShellLinks inTest = new WinShellLinks(); + @BeforeEach public void setup(@TempDir Path tempDir) throws IOException { this.linkTarget = tempDir.resolve("link.target"); @@ -31,16 +33,14 @@ public void setup(@TempDir Path tempDir) throws IOException { @Test public void testGetStartupFolderPath() { - WinShellLinks winShellLinks = new WinShellLinks(); - Assertions.assertDoesNotThrow(() -> winShellLinks.getPathToStartupFolder()); + Assertions.assertDoesNotThrow(() -> inTest.getPathToStartupFolder()); } @Test public void testShellLinkCreation() { - WinShellLinks winShellLinks = new WinShellLinks(); shortcut = linkTarget.getParent().resolve("short.lnk"); - int returnCode = winShellLinks.createShortcut(linkTarget.toString(), shortcut.toString(), "asd"); + int returnCode = inTest.createShortcut(linkTarget.toString(), shortcut.toString(), "asd"); Assertions.assertEquals(0, returnCode); Assertions.assertTrue(Files.exists(shortcut)); @@ -52,9 +52,7 @@ public void testShellLinkCreation() { "bar, '62 00 61 00 72 00 00 00'" }) public void testGetNullTerminatedUTF16Representation(String input, @ConvertWith(ByteArrayConverter.class) byte[] expected) { - WinShellLinks winShellLinks = new WinShellLinks(); - - var result = winShellLinks.getNullTerminatedUTF16Representation(input); + var result = inTest.getNullTerminatedUTF16Representation(input); Assertions.assertArrayEquals(expected, result); } From adb5678c088e688fd8d452060feaf9414460f10d Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Sun, 15 Jan 2023 17:53:57 +0100 Subject: [PATCH 11/21] refine doc --- .../org/cryptomator/windows/autostart/WinShellLinks.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/cryptomator/windows/autostart/WinShellLinks.java b/src/main/java/org/cryptomator/windows/autostart/WinShellLinks.java index ba0b86a..5d1fa8c 100644 --- a/src/main/java/org/cryptomator/windows/autostart/WinShellLinks.java +++ b/src/main/java/org/cryptomator/windows/autostart/WinShellLinks.java @@ -15,8 +15,8 @@ public class WinShellLinks { /** * Create a Windows shortcut file to the given target, at the specified location and with a description. * - * @param target path of the target the shortcut points to - * @param storagePath path where the shortcut is created + * @param target path of the shortcut target + * @param storagePath full path where the shortcut will be created (including filename & extension) * @param description string inserted in the description field of the shortcut. * @return {@code 0} if everything worked, otherwise an HRESULT error code */ @@ -31,7 +31,7 @@ public int createShortcut(String target, String storagePath, String description) /** * Gets the file system path of the startup folder. Creates all directories in the path, if necessary. * - * @return path to the startup folder with no trailing \ or {@code null}, if the folder is not defined or cannot be created + * @return path to the startup folder with no trailing \ or {@code null}, if the folder is not defined and cannot be created */ public String getPathToStartupFolder() { return Native.INSTANCE.createAndGetStartupFolderPath(); From 5d7ac7d25ae5c3d5316b54f41122283747bfde82 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Sun, 15 Jan 2023 18:00:22 +0100 Subject: [PATCH 12/21] fix javadoc error --- .../java/org/cryptomator/windows/autostart/WinShellLinks.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/cryptomator/windows/autostart/WinShellLinks.java b/src/main/java/org/cryptomator/windows/autostart/WinShellLinks.java index 5d1fa8c..40a1a3a 100644 --- a/src/main/java/org/cryptomator/windows/autostart/WinShellLinks.java +++ b/src/main/java/org/cryptomator/windows/autostart/WinShellLinks.java @@ -16,7 +16,7 @@ public class WinShellLinks { * Create a Windows shortcut file to the given target, at the specified location and with a description. * * @param target path of the shortcut target - * @param storagePath full path where the shortcut will be created (including filename & extension) + * @param storagePath full path where the shortcut will be created (including filename & file extension) * @param description string inserted in the description field of the shortcut. * @return {@code 0} if everything worked, otherwise an HRESULT error code */ From c7400c6f836b2df0c0ce7512ed72c016ff63371b Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Sun, 15 Jan 2023 18:18:36 +0100 Subject: [PATCH 13/21] sign published dll --- .github/workflows/build.yml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f2a0c4f..989f048 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -24,7 +24,18 @@ jobs: run: mvn versions:set --file ./pom.xml -DnewVersion=${GITHUB_REF##*/} - name: Build and Test id: buildAndTest - run: mvn -B clean install -Pdependency-check + run: mvn -B clean test -Pdependency-check + - name: Codesign DLL + uses: skymatic/code-sign-action@v2 + with: + certificate: ${{ secrets.WIN_CODESIGN_P12_BASE64 }} + password: ${{ secrets.WIN_CODESIGN_P12_PW }} + certificatesha1: 5FC94CE149E5B511E621F53A060AC67CBD446B3A + timestampUrl: 'http://timestamp.digicert.com' + folder: ./target/classes + - name: Package and Install + id: packAndInstall + run: mvn -B install - uses: actions/upload-artifact@v3 with: name: artifacts From 86e97ace3b718e70674e6692882a5ee3061acf43 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Sun, 15 Jan 2023 18:18:56 +0100 Subject: [PATCH 14/21] replace deprecated release action --- .github/workflows/build.yml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 989f048..1578029 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -41,11 +41,10 @@ jobs: name: artifacts path: target/*.jar - name: Create Release - uses: actions/create-release@v1 # NOTE: action is unmaintained and repo archived + uses: softprops/action-gh-release@v1 if: startsWith(github.ref, 'refs/tags/') - env: - 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 + name: Release ${{ github.ref }} + prerelease: true + token: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }} + generate_release_notes: true \ No newline at end of file From 11f00ce243baaf863355820bb5d79c9702677265 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Mon, 16 Jan 2023 12:42:30 +0100 Subject: [PATCH 15/21] docs again --- .../java/org/cryptomator/windows/autostart/WinShellLinks.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/cryptomator/windows/autostart/WinShellLinks.java b/src/main/java/org/cryptomator/windows/autostart/WinShellLinks.java index 40a1a3a..a1b26f0 100644 --- a/src/main/java/org/cryptomator/windows/autostart/WinShellLinks.java +++ b/src/main/java/org/cryptomator/windows/autostart/WinShellLinks.java @@ -31,7 +31,7 @@ public int createShortcut(String target, String storagePath, String description) /** * Gets the file system path of the startup folder. Creates all directories in the path, if necessary. * - * @return path to the startup folder with no trailing \ or {@code null}, if the folder is not defined and cannot be created + * @return path to the startup folder with no trailing \, or {@code null} if the folder is not defined and cannot be created */ public String getPathToStartupFolder() { return Native.INSTANCE.createAndGetStartupFolderPath(); From 5c5fbfbdd8e992dce9a1cb44e1e1079cb214d169 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Mon, 16 Jan 2023 13:13:00 +0100 Subject: [PATCH 16/21] allow to skip native compilation via flag to not overwrite signed dll --- .github/workflows/build.yml | 4 +-- pom.xml | 59 ++++++++++++++++++++++--------------- 2 files changed, 38 insertions(+), 25 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1578029..fed7d52 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -32,10 +32,10 @@ jobs: password: ${{ secrets.WIN_CODESIGN_P12_PW }} certificatesha1: 5FC94CE149E5B511E621F53A060AC67CBD446B3A timestampUrl: 'http://timestamp.digicert.com' - folder: ./target/classes + folder: ./src/main/resources - name: Package and Install id: packAndInstall - run: mvn -B install + run: mvn -B install -DskipNativeCompile - uses: actions/upload-artifact@v3 with: name: artifacts diff --git a/pom.xml b/pom.xml index 333c4d4..2ede01e 100644 --- a/pom.xml +++ b/pom.xml @@ -147,29 +147,6 @@ - - org.codehaus.mojo - exec-maven-plugin - 3.0.0 - - - - exec - - compile - - make - ${project.basedir} - - ${java.home} - - - install - - - - - maven-resources-plugin 3.2.0 @@ -285,6 +262,42 @@ + + compile-native + + + !skipNativeCompile + + + + + + org.codehaus.mojo + exec-maven-plugin + 3.0.0 + + + + exec + + compile + + make + ${project.basedir} + + ${java.home} + + + install + + + + + + + + + sign From 8ec9cde748f6efd080fdef69f2f01dcc004a5609 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Mon, 16 Jan 2023 13:28:23 +0100 Subject: [PATCH 17/21] preparing 1.2.0 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2ede01e..919a692 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ 4.0.0 org.cryptomator integrations-win - 1.2.0-SNAPSHOT + 1.2.0 Cryptomator Integrations for Windows Provides optional Windows services used by Cryptomator From f2f0c98e572b4e8b54ba9d035794ec3b825a0378 Mon Sep 17 00:00:00 2001 From: Cryptobot Date: Mon, 16 Jan 2023 13:33:22 +0100 Subject: [PATCH 18/21] New Crowdin updates (#15) New translations strings.properties Danish; Portuguese; Slovenian; Vietnamese; [ci skip] --- src/main/resources/WinIntegrationsBundle_da.properties | 1 + src/main/resources/WinIntegrationsBundle_pt.properties | 2 +- src/main/resources/WinIntegrationsBundle_sl.properties | 0 src/main/resources/WinIntegrationsBundle_vi.properties | 2 +- 4 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 src/main/resources/WinIntegrationsBundle_da.properties create mode 100644 src/main/resources/WinIntegrationsBundle_sl.properties diff --git a/src/main/resources/WinIntegrationsBundle_da.properties b/src/main/resources/WinIntegrationsBundle_da.properties new file mode 100644 index 0000000..b7b0217 --- /dev/null +++ b/src/main/resources/WinIntegrationsBundle_da.properties @@ -0,0 +1 @@ +org.cryptomator.windows.keychain.displayName=Windows Databeskyttelse \ No newline at end of file diff --git a/src/main/resources/WinIntegrationsBundle_pt.properties b/src/main/resources/WinIntegrationsBundle_pt.properties index 85f4a7a..cad370f 100644 --- a/src/main/resources/WinIntegrationsBundle_pt.properties +++ b/src/main/resources/WinIntegrationsBundle_pt.properties @@ -1 +1 @@ -org.cryptomator.windows.keychain.displayName=Windows Data Protection \ No newline at end of file +org.cryptomator.windows.keychain.displayName=Proteção de dados do Windows \ No newline at end of file diff --git a/src/main/resources/WinIntegrationsBundle_sl.properties b/src/main/resources/WinIntegrationsBundle_sl.properties new file mode 100644 index 0000000..e69de29 diff --git a/src/main/resources/WinIntegrationsBundle_vi.properties b/src/main/resources/WinIntegrationsBundle_vi.properties index 9b7f58e..578ccfb 100644 --- a/src/main/resources/WinIntegrationsBundle_vi.properties +++ b/src/main/resources/WinIntegrationsBundle_vi.properties @@ -1 +1 @@ -org.cryptomator.windows.keychain.displayName=Bảo vệ Dữ liệu Windows \ No newline at end of file +org.cryptomator.windows.keychain.displayName=Thuật toán Bảo vệ Dữ liệu của Windows \ No newline at end of file From b7c833a42153b17047734e67077de0ac5bdfd7ce Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Mon, 16 Jan 2023 19:53:52 +0100 Subject: [PATCH 19/21] use default release name for release action --- .github/workflows/build.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index fed7d52..58ee700 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -44,7 +44,6 @@ jobs: uses: softprops/action-gh-release@v1 if: startsWith(github.ref, 'refs/tags/') with: - name: Release ${{ github.ref }} prerelease: true token: ${{ secrets.CRYPTOBOT_RELEASE_TOKEN }} generate_release_notes: true \ No newline at end of file From 2837b658e5f480c2310f27633e19e3b7bad5f814 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Wed, 1 Feb 2023 22:28:01 +0100 Subject: [PATCH 20/21] fixes #19 --- .../windows/revealpath/ExplorerRevealPathService.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/cryptomator/windows/revealpath/ExplorerRevealPathService.java b/src/main/java/org/cryptomator/windows/revealpath/ExplorerRevealPathService.java index 46ce395..340feb5 100644 --- a/src/main/java/org/cryptomator/windows/revealpath/ExplorerRevealPathService.java +++ b/src/main/java/org/cryptomator/windows/revealpath/ExplorerRevealPathService.java @@ -20,8 +20,13 @@ public class ExplorerRevealPathService implements RevealPathService { public void reveal(Path p) throws RevealFailedException { try { var attrs = Files.readAttributes(p, BasicFileAttributes.class, LinkOption.NOFOLLOW_LINKS); - var args = (attrs.isDirectory() ? "" : "/select,") + "\"" + p.toString() + "\""; - ProcessBuilder pb = new ProcessBuilder().command("explorer", args); + ProcessBuilder pb = new ProcessBuilder(); + if(attrs.isDirectory()) { + pb.command("explorer.exe",p.toString()); + } else { + pb.command("explorer.exe ","/select,",p.toString()); + } + var process = pb.start(); if (process.waitFor(5000, TimeUnit.MILLISECONDS)) { int exitValue = process.exitValue(); From ead844d8a7a34eff583dcd082fe9d56634c3aaa0 Mon Sep 17 00:00:00 2001 From: Armin Schrenk Date: Wed, 8 Feb 2023 10:31:37 +0100 Subject: [PATCH 21/21] fixes #20 --- .../windows/revealpath/ExplorerRevealPathService.java | 4 ++-- .../windows/revealpath/ExplorerRevealPathServiceTest.java | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/cryptomator/windows/revealpath/ExplorerRevealPathService.java b/src/main/java/org/cryptomator/windows/revealpath/ExplorerRevealPathService.java index 340feb5..687dd3e 100644 --- a/src/main/java/org/cryptomator/windows/revealpath/ExplorerRevealPathService.java +++ b/src/main/java/org/cryptomator/windows/revealpath/ExplorerRevealPathService.java @@ -22,9 +22,9 @@ public void reveal(Path p) throws RevealFailedException { var attrs = Files.readAttributes(p, BasicFileAttributes.class, LinkOption.NOFOLLOW_LINKS); ProcessBuilder pb = new ProcessBuilder(); if(attrs.isDirectory()) { - pb.command("explorer.exe",p.toString()); + pb.command("explorer.exe", "\""+p+"\""); } else { - pb.command("explorer.exe ","/select,",p.toString()); + pb.command("explorer.exe ","/select,","\""+p+"\""); } var process = pb.start(); diff --git a/src/test/java/org/cryptomator/windows/revealpath/ExplorerRevealPathServiceTest.java b/src/test/java/org/cryptomator/windows/revealpath/ExplorerRevealPathServiceTest.java index f70e7b7..eb77dd7 100644 --- a/src/test/java/org/cryptomator/windows/revealpath/ExplorerRevealPathServiceTest.java +++ b/src/test/java/org/cryptomator/windows/revealpath/ExplorerRevealPathServiceTest.java @@ -15,11 +15,14 @@ public class ExplorerRevealPathServiceTest { @Test public void testReveal(@TempDir Path tmpDir) throws IOException { - Path foo = tmpDir.resolve("foo.txt"); + Path foo = tmpDir.resolve("foo=.txt"); + Path bar = tmpDir.resolve("bar="); Files.createFile(foo); + Files.createDirectory(bar); Assertions.assertDoesNotThrow(() -> service.reveal(foo)); + Assertions.assertDoesNotThrow(() -> service.reveal(bar)); Assertions.assertTrue(Files.exists(foo)); }