C:\Users\tom\dev\repos\gh\thomasdarimont\training\java-workbench\java20\src>java --add-opens=java.base/sun.nio.fs=ALL-UNNAMED --show-version Main.java
openjdk 20 2023-03-21
OpenJDK Runtime Environment (build 20+36-2344)
OpenJDK 64-Bit Server VM (build 20+36-2344, mixed mode, sharing)
Drive C: - Fixed Disk
Drive Z: - Not Fixed Disk
C:\Users\tom\dev\repos\gh\thomasdarimont\training\java-workbench\java20\src>"c:\Program Files\OpenJDK\jdk-11\bin"\java --add-opens=java.base/sun.nio.fs=ALL-UNNAMED --show-version Main.java
openjdk 11.0.2 2019-01-15
OpenJDK Runtime Environment 18.9 (build 11.0.2+9)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.2+9, mixed mode)
Drive C: - Fixed Disk
Drive Z: - Not Fixed Disk
C:\Users\tom\dev\repos\gh\thomasdarimont\training\java-workbench\java20\src>"c:\Program Files\OpenJDK\openjdk-8u262-b10\bin"\javac Main.java
C:\Users\tom\dev\repos\gh\thomasdarimont\training\java-workbench\java20\src>"c:\Program Files\OpenJDK\openjdk-8u262-b10\bin"\java -cp . Main
Drive C: - Fixed Disk
Drive Z: - Not Fixed Disk
Created
April 11, 2023 22:04
-
-
Save thomasdarimont/86d6ef7b62d7c36bdeea7ec76ddc0a2e to your computer and use it in GitHub Desktop.
PoC for replacing the native code in Lomboks installer https://github.com/projectlombok/lombok/blob/master/src/installer/lombok/installer/WindowsDriveInfo.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.lang.reflect.InvocationTargetException; | |
import java.lang.reflect.Method; | |
import java.util.ArrayList; | |
import java.util.List; | |
public class Main { | |
// --add-opens=java.base/sun.nio.fs=ALL-UNNAMED | |
public static void main(String[] args) throws Exception { | |
WindowsDriveInfo info = new WindowsDriveInfo(); | |
for (String letter : info.getLogicalDrives()) { | |
System.out.printf("Drive %s: - %s\n", letter, | |
info.isFixedDisk(letter) ? "Fixed Disk" : "Not Fixed Disk"); | |
} | |
} | |
public static class WindowsDriveInfo { | |
/** | |
* Calls kernel32's GetLogicalDrives, which returns an int containing | |
* flags; bit 0 corresponds to drive A, bit 25 to drive Z. on = disk exists. | |
*/ | |
private static final Method GET_LOGICAL_DRIVES; | |
/** | |
* Mirror of kernel32's GetDriveTypeA. You must pass in 'A:\\' - | |
* so including both a colon and a backslash! | |
* <p> | |
* 0 = error | |
* 1 = doesn't exist | |
* 2 = removable drive | |
* 3 = fixed disk | |
* 4 = remote (network) disk | |
* 5 = cd-rom | |
* 6 = ram disk | |
*/ | |
private static final Method GET_DRIVE_TYPE; | |
static { | |
try { | |
Class<?> cls = Class.forName("sun.nio.fs.WindowsNativeDispatcher"); | |
Method getLogicalDrivesMethod = cls.getDeclaredMethod("GetLogicalDrives"); | |
getLogicalDrivesMethod.setAccessible(true); | |
Method getDriveTypeMethod = cls.getDeclaredMethod("GetDriveType", String.class); | |
getDriveTypeMethod.setAccessible(true); | |
GET_LOGICAL_DRIVES = getLogicalDrivesMethod; | |
GET_DRIVE_TYPE = getDriveTypeMethod; | |
} catch (Exception e) { | |
throw new RuntimeException(e); | |
} | |
} | |
/** | |
* Return a list of all available drive letters, such as ["A", "C", "D"]. | |
*/ | |
public List<String> getLogicalDrives() { | |
int flags = getLogicalDrives0(); | |
List<String> letters = new ArrayList<String>(); | |
for (int i = 0; i < 26; i++) { | |
if ((flags & (1 << i)) != 0) letters.add(Character.toString((char) ('A' + i))); | |
} | |
return letters; | |
} | |
private static int getLogicalDrives0() { | |
try { | |
return (int) GET_LOGICAL_DRIVES.invoke(null); | |
} catch (IllegalAccessException e) { | |
throw new RuntimeException(e); | |
} catch (InvocationTargetException e) { | |
throw new RuntimeException(e); | |
} | |
} | |
/** | |
* Feed it a drive letter (such as 'A') to see if it is a fixed disk. | |
*/ | |
public boolean isFixedDisk(String letter) { | |
if (letter.length() != 1) throw new IllegalArgumentException("Supply 1 letter, not: " + letter); | |
char drive = Character.toUpperCase(letter.charAt(0)); | |
if (drive < 'A' || drive > 'Z') throw new IllegalArgumentException( | |
"A drive is indicated by a letter, so A-Z inclusive. Not " + drive); | |
return getDriveType0(drive) == 3L; | |
} | |
private static int getDriveType0(char drive) { | |
try { | |
return (int) GET_DRIVE_TYPE.invoke(null, drive + ":\\"); | |
} catch (IllegalAccessException e) { | |
throw new RuntimeException(e); | |
} catch (InvocationTargetException e) { | |
throw new RuntimeException(e); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment