Skip to content

#59 Fix Windows SMART retrieval with persistent elevated agent and Win32 device probing - #220

Merged
IanReyes44 merged 2 commits into
devfrom
smart-persistence
Sep 7, 2026
Merged

#59 Fix Windows SMART retrieval with persistent elevated agent and Win32 device probing#220
IanReyes44 merged 2 commits into
devfrom
smart-persistence

Conversation

@IanReyes44

Copy link
Copy Markdown
Contributor

Summary

This PR addresses Windows SMART data retrieval failures and improves the user experience by replacing per-query UAC prompts with a persistent elevated background agent and enhancing device path probing with NVMe/SAT hints.

Key Changes

1. Persistent Elevated Background Agent (SmartEscalation.java)

  • Single UAC Elevation per Session: Replaced the previous single-shot UAC elevation model with a persistent elevated PowerShell agent running in the background. Users now only need to grant UAC approval once per session.
  • File-based IPC Protocol: Built an IPC channel in %LOCALAPPDATA%\JDiskMark using request (smart-req-<device>.txt), status (smart-ipc-<device>.status), and result (smart-ipc-<device>.json) files encoded in UTF-8 without BOM.
  • Graceful Lifecycle Management:
    • Registered a JVM shutdown hook (smart-agent-stopper) that drops smart-agent-stop.txt to cleanly terminate the elevated agent process upon application exit.
    • Added timeouts and recovery logic for UAC launching (45s), agent initialization (20s), and individual SMART queries (30s) to handle cancellation or stalled processes.
  • Quoting & Path Safety: Fixed Start-Process argument quoting in PowerShell invocation to correctly handle paths with spaces.

2. Multi-Pass Device Probing & Fallback (Smart.java & SmartEscalation.java)

  • Multi-pass Candidate Probing:
    • Pass 1: Probes simple paths (/dev/pdN and bare pdN).
    • Pass 2: Probes Win32 paths (\\.\PhysicalDriveN) with plain, -d nvme, and -d sat hints to ensure support across NVMe controllers and SAT devices on Windows.
  • Error-JSON Fallback: When a device open fails (bit 1 set in smartctl exit code), the parser retains and returns the first available JSON output, allowing the UI to extract drive identity (model, serial number, firmware) even if SMART attribute reading is restricted.

Verification

  • Built and verified core application with mvn clean install -pl jdm-core -am --no-transfer-progress.
  • Tested Windows SMART reading with UAC elevation prompt occurring only once.
  • Verified clean process termination of the PowerShell agent on application close.

…device probing

- Enhanced getSmartDirect to probe /dev/pdN, pdN, and Win32 PhysicalDrive paths with -d nvme / -d sat hints, with fallback to error-JSON.
- Replaced single-shot UAC escalation with a persistent elevated PowerShell agent running via IPC in %LOCALAPPDATA%\JDiskMark.
- Fixed Start-Process argument quoting in SmartEscalation to handle paths with spaces.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves Windows SMART retrieval by introducing a persistent elevated PowerShell agent (reducing repeated UAC prompts) and by expanding device probing to include Win32 PhysicalDrive paths with NVMe/SAT hints, plus a JSON fallback path when device-open fails.

Changes:

  • Replaced per-query UAC elevation with a persistent elevated PowerShell agent using file-based IPC in %LOCALAPPDATA%\JDiskMark.
  • Added multi-pass device candidate probing on Windows, including \\.\PhysicalDriveN with -d nvme / -d sat hints.
  • Added “error-JSON” fallback handling when smartctl returns JSON but sets the “device open failed” exit-code bit.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
jdm-core/src/main/java/jdiskmark/SmartEscalation.java Implements the persistent elevated PowerShell agent, IPC protocol, and timeouts/shutdown handling.
jdm-core/src/main/java/jdiskmark/Smart.java Expands Windows probing candidates and adds error-JSON fallback behavior in the direct execution path.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread jdm-core/src/main/java/jdiskmark/SmartEscalation.java Outdated
Comment on lines +140 to +142
Path scriptFile = ipcDir.resolve("smart-agent.ps1");
Files.writeString(scriptFile, script, StandardCharsets.UTF_8);
String scriptPs = scriptFile.toString().replace("'", "''");

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@IanReyes44 what do you think about this solution: instead of generating this script where another user can modify it we just create a hard version control script that is installed along with our app which will require admin to modify it. in the source repo we can place it in jdm-core/src/main/resources/smartctl/smart-agent.ps1 when we're installing after smartctl folder is expanded we can copy this src file to:

Program Files/JDiskMark/app/smartctl/
├── smartctl.exe
├── smart-agent.ps1   ← here
└── ...

the current generated script has some dynamic elements so we'd either have to pass those in as parameters or have the script automatically calculate that.

Comment thread jdm-core/src/main/java/jdiskmark/Smart.java Outdated
@jamesmarkchan

Copy link
Copy Markdown
Member

tested build just now, definitely looks to be working!

image

let me take a look at the code to make sure it looks maintainable....

@jamesmarkchan jamesmarkchan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That security finding from copilot makes sense and can be addressed by making the script live in the installation dir. like C:\Program Files\JDiskMark 0.8.0\....

if this change sounds good we should be able to get this into the next release!

the other two findings from copilot also make sense to do.

one more thing! we allow on windows to run multiple versions, how about changing the folder location where these messages are passed back and forth to <userhome>/.jdm/<install_version>/

- Fix PowerShell -ArgumentList quoting (Copilot medium): switch from
  inline string escaping to Base64-encoded -EncodedCommand so paths
  containing spaces or special characters are never exposed to
  Start-Process argument-list parsing

- Fix Win32 PhysicalDrive probe guard (Copilot medium): tighten
  startsWith('pd') to matches('^pd\d+$') so only valid numeric
  device names (pd0, pd1...) generate \\.\PhysicalDriveN paths

- Fix agent script security (Copilot high / jamesmarkchan): move
  smart-agent.ps1 from the user-writable %LOCALAPPDATA% temp dir to
  a static resource bundled alongside smartctl.exe in Program Files
  (admin-write-only). Eliminates the privilege escalation window where
  a same-user process could tamper with the script between write and
  elevation.

- Version-scope the IPC directory (jamesmarkchan): change IPC dir
  from %LOCALAPPDATA%\JDiskMark to ~/.jdm/<install_version>/smart-ipc
  (matching App.APP_CACHE_DIR) so side-by-side installs of different
  versions do not share or interfere with each other's IPC files.

Files changed:
  jdm-core/pom.xml                              - copy smart-agent.ps1 into target/smartctl/ during build
  jdm-core/src/main/resources/smartctl/         - new static smart-agent.ps1 with param block
  jdm-core/src/main/java/jdiskmark/SmartEscalation.java - all of the above
  jdm-core/src/main/java/jdiskmark/Smart.java   - Javadoc update
@IanReyes44

Copy link
Copy Markdown
Contributor Author

Hi @jamesmarkchan,

All feedback has been addressed in commit 4ab0033:

Admin-only script location: Bundled smart-agent.ps1 into the installation directory alongside smartctl.exe instead of writing to %LOCALAPPDATA%.
Version-scoped IPC directory: Moved IPC communication to ~/.jdm//smart-ipc to match App.APP_CACHE_DIR and prevent side-by-side version collisions.
Path handling: Used PowerShell -EncodedCommand (Base64) to ensure paths with spaces or special characters resolve reliably.
Drive regex & docs: Fixed physical drive regex pattern and updated Javadocs.
Tested locally with the MSI installer and SMART retrieval works cleanly. Ready for merge!

@IanReyes44
IanReyes44 merged commit 0affe5a into dev Sep 7, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants