Skip to content

Instantly share code, notes, and snippets.

@thomasdarimont
Created April 11, 2023 22:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thomasdarimont/86d6ef7b62d7c36bdeea7ec76ddc0a2e to your computer and use it in GitHub Desktop.
Save thomasdarimont/86d6ef7b62d7c36bdeea7ec76ddc0a2e to your computer and use it in GitHub Desktop.
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
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