Parsing Every Log Format: The Timestamp Problem in LogSleuth
Every application writes logs differently, and timestamps are a disaster. Here's the 15-heuristic fallback chain LogSleuth uses to parse them, and why it has to exist.
Read article →18 Apr 2026 3 min read
“The action can’t be completed because the file is open in another program.” No program name. No PID. Just go away.
Resource Monitor can find it if you know where to look, but it’s slow and doesn’t help when the lock is held by a remote machine over SMB. I got tired of it and built two tools. One in Rust, one in pure C. Same problem, completely different design decisions.
SMB file locks and local process handles are not the same thing and don’t share an API.
If someone on your network has mounted a share and left a file open, that’s NetFileEnum from netapi32.dll — it enumerates open files across all active SMB sessions and gives you the user, path, and an ID you can pass to NetFileClose to kill it. Both my tools use this. Both require admin elevation.
The catch: NetFileEnum only sees SMB sessions. If Notepad on the same machine is holding the file, NetFileEnum returns nothing. For local handles you need something else — Process Explorer, Sysinternals Handle.exe, or NtQuerySystemInformation. I keep Process Explorer in my toolkit for exactly that reason.
LockSmith is about 4 MB, starts in half a second, and runs in ~20 MB of RAM. Single eframe::App, calls NetFileEnum on refresh, renders a table with filter and force-close. I used egui instead of Tauri specifically for the cold-start time — when something is stuck and you need to kill a lock, 0.5 seconds beats 1.5 seconds.
One thing to get right with NetFileEnum: it doesn’t always return everything in one call. The resume_handle parameter is how you loop through the full result set. Forgetting to loop means you silently miss entries when there are a lot of open files.
Same job. 134 KB. No C runtime — no stdio, no malloc, nothing. Raw Win32 throughout.
The reason to do this isn’t cleverness — it’s that a recovery tool should have as few dependencies as possible. No DLL loader surprises, no “VCRUNTIME140.dll is missing” when you copy it to a server you’ve never touched before. It’s the binary I put on a USB stick.
For a tool any larger, this approach would be a maintenance nightmare. At 1,500 lines it’s manageable.
For local process locks, the options are:
handle64.exe -a -u C:\path\to\file — straightforward, elevated, does what it saysNtQuerySystemInformation(SystemExtendedHandleInformation) — that’s how Sysinternals does it, but those structures are undocumented and have changed between Windows versionsI haven’t built the local handle case into either tool yet, mostly because the undocumented API makes it hard to commit to long-term. Might happen eventually.
Both tools on GitHub: LockSmith, HandleHunter. MIT licensed.