判断文件是否存在打开的文件映射——有无更简洁的实现方法?
Great question! The SetEndOfFile workaround works, but it's definitely clunky—modifying the file just to check its state feels like a hack. Here are a couple cleaner, non-intrusive approaches:
1. Enumerate System Handles with NtQuerySystemInformation
This method lets you inspect all active handles in the system to see if any are section objects (the kernel-level objects behind file mappings) linked to your target file. Here's a high-level breakdown:
- Call
NtQuerySystemInformationwith theSystemHandleInformationclass to get a list of all system handles. - For each handle, resolve which process it belongs to, then use
NtQueryObjectto check if the handle is aSectionobject. - For section handles, query their underlying file object (using
NtQuerySectionwithSectionBasicInformation) and compare it to your target file's handle/information.
While this requires a bit more code, it's non-intrusive (no file modifications) and gives you precise details about existing mappings. Note that you'll need the SE_DEBUG_NAME privilege to inspect handles from other processes.
2. Use GetFileInformationByHandleEx with FileProcessIdsUsingFileInformation
First, use GetFileInformationByHandleEx with the FileProcessIdsUsingFileInformation flag to get all processes that have the file open. Then, for each process:
- Enumerate its handles (again using
NtQuerySystemInformationfor precision). - Check if any of those handles are section objects tied to your file.
This narrows down the processes you need to inspect, making the enumeration faster than scanning every handle in the system.
3. Lightweight Alternative: SetFileValidData (Still Intrusive, But Faster)
If you don't mind a minor system call that doesn't actually modify the file's content (unlike SetEndOfFile), you can use SetFileValidData. This API attempts to mark a range of the file as valid, and it will fail with ERROR_USER_MAPPED_FILE if there are active mappings. The catch? You need administrative privileges to call it, and it still touches file metadata.
Quick Comparison
| Method | Intrusive? | Privileges Needed | Complexity |
|---|---|---|---|
SetEndOfFile | Yes (temporarily modifies file size) | None | Low |
NtQuerySystemInformation Enumeration | No | SE_DEBUG_NAME | Medium |
SetFileValidData | Minimal (metadata only) | Admin | Low |
For most cases, the handle enumeration method is the cleanest long-term solution—even if it requires a bit more code, it avoids touching the file entirely and gives you full visibility into what's mapping it.
内容的提问来源于stack exchange,提问作者H. Arlinghaus

