Secure File Deletion (Data Shredding) with CBFS Filter
Deleting a file through the normal Windows API does not erase its data. It removes the filesystem's reference to the blocks that held the data, and those blocks remain physically present and recoverable, often trivially, with common undelete tools, until something else happens to overwrite them. For some purposes that is fine. When a deletion is meant to satisfy an actual destruction requirement, such as the right to erasure discussed in Building GDPR-Aligned Applications with Callback Technologies, "deleted" has to mean the content is actually gone. CBFilter can enforce this by intercepting a delete request and overwriting the file's content before the underlying deletion is allowed to proceed.
Catching the Delete Request
Add a filter rule with the FS_CE_BEFORE_DELETE flag for the files or directories you need to shred rather than merely delete:
filter.AddFilterRule(@"C:\SensitiveData\*.*", Constants.ACCESS_NONE,
Constants.FS_CE_BEFORE_DELETE, Constants.FS_NE_NONE);
BeforeDeleteFile fires while the file still exists on disk, before the final close that removes it. It fires regardless of which of the two ways Windows initiates a delete: a file opened with FILE_FLAG_DELETE_ON_CLOSE, or an explicit disposition set on an already-open handle. The event's RequestType parameter tells you which one triggered it (DEL_REQ_OPEN_FLAG or DEL_REQ_SET_DISPOSITION), though the overwrite logic itself does not need to treat the two cases differently.
BeforeDeleteFile cannot be used to block the deletion; that is the purpose of the separate BeforeCanFileBeDeleted event. For shredding, that is not a limitation: the goal is to destroy the content before the delete completes, not to prevent the delete from happening.
Overwriting the Content
Use CreateFileDirect to open the file for writing without going through the rest of your filter's own rule processing, then overwrite it with the standard Win32 WriteFile function before closing the handle:
``` void BeforeDeleteFile(object sender, CBFilterBeforeDeleteFileEventArgs e) { int creationStatus = 0; long handle = filter.CreateFileDirect(e.FileName, /Synchronize:/ true, GENERIC_WRITE, Constants.FILESYS_SHARE_READ | Constants.FILESYS_SHARE_WRITE | Constants.FILESYS_SHARE_DELETE, OPEN_EXISTING, /flagsAndAttributes:/ 0, /closeImmediately:/ false, /securityDescriptor:/ null, Constants.CFD_SEND_VIA_STACK, ref creationStatus);
if (handle == INVALID_HANDLE_VALUE) return; // Could not open the file directly; nothing to overwrite.
IntPtr rawHandle = new IntPtr(handle); try { long fileSize; GetFileSizeEx(rawHandle, out fileSize); OverwriteWithRandomData(rawHandle, fileSize); FlushFileBuffers(rawHandle); } finally { filter.CloseHandle(handle); } } ```
OverwriteWithRandomData is application code: seek to the start of the file, write successive chunks of cryptographically random bytes (or zeros, if your policy only needs to defeat casual recovery rather than resist forensic analysis) until the full size reported by GetFileSizeEx is covered. FlushFileBuffers matters here: without it, the overwritten data may still be sitting in the OS's write cache rather than on the physical medium when the subsequent delete completes.
What a Single-Pass Overwrite Does and Does Not Guarantee
A single overwrite pass followed by deletion is enough to defeat undelete utilities and most casual forensic recovery on traditional magnetic storage, where a write genuinely replaces the data in place. It does not make the same guarantee on flash-based storage (SSDs, USB drives, and most modern laptop storage). Flash controllers use wear leveling and may write replacement data to a different physical location than the one being logically overwritten, leaving the original data intact in a block the filesystem no longer references but the drive itself has not erased. If your compliance requirement extends to storage media where this applies, an application-level overwrite is a useful additional step, but it is not on its own a substitute for full-disk encryption (so that the data is unrecoverable without the key regardless of which physical blocks it lives in) or the storage device's own secure-erase command.
Getting Started with CBFilter
You can find an evaluation version of the SDK for your platform and programming language in the Download Center. After downloading and installing the SDK, you will receive a library, sample code, and comprehensive documentation on your system. The documentation includes a "Getting Started" section with programming instructions. Additionally, free technical support is available during the evaluation phase.
We appreciate your feedback. If you have any questions, comments, or suggestions about this article please contact our support team at support@callback.com.