Undelete Logo
Copyright © 1997-2000 Mark Russinovich and Bryce Cogswell
Last Updated February 24, 2000, Version 2.02
Introduction Although NT 4.0 provides a Recycle Bin, it is of very limited use. Only files deleted from the Explorer GUI end up being placed there. Any files zapped from a command window or from within a program are lost forever. Fundelete is a utility that replaces NT 4.0's Recycle Bin to provide full protection of files deleted from anywhere. Fundelete includes the same configurability as Recycle Bin's Properties dialog, including which drives should have protection enabled, and how large the Fundelete Bin should be allowed to grow. Fundelete also provides a filtering dialog that allows you to prevent files of specific extensions not to be sent to the Bin, such as editor backup files, and temporary files. You can also specify directories that will be excluded from protection.

Note that Fundelete does not enable you to recover files that you deleted before you have installed Fundelete.
A Note About the Name Fundelete was originally named Undelete for Windows NT. A year after we released our "Undelete" Executive Software decided to rename one of their products, which provides some of the same functionality as our utility, to Undelete for Windows NT. We were subsequently informed by attorneys representing Executive Software International, Inc. that we were violating their registered trademark on the word "undelete" by using it in the title of our program. Apparantly, the word "undelete", despite being standard computer terminology and arguably a necessary addendum to the modern English language (it is listed in many computer dictionaries), has been owned by Executive Software since 1987 (we wonder if Microsoft knew that when they added the undelete command to DOS 5 in 1991). We therefore renamed our Undelete for Windows NT to Fundelete for Windows NT.
Installation and Use Fundelete is installed with a self-extracting install program. No file extension filters are automatically installed, so after installation you might want to run the Fundelete filter dialog (placed in the Fundelete program group) and add to it extensions and directories that you want Fundelete support disabled for. After rebooting, any files you delete from within programs or the command prompt , which are not being filtered from protection, will be moved to the Recycle Bin. Simply use the Fundelete Bin as you would for files deleted from Explorer to recover deleted files.
The Source Code We have posted the source code to one of the modules of the Fundelete device driver. This module, undelete.c, demonstrates several powerful techniques that are useful for device driver writers, and that are not documented anywhere else. Several of them include :
  • Synchronizing access to a file that is accessed from a GUI and a driver. The Fundelete GUI passes a mutex handle to the driver, which obtains a mutex object pointer from it. Thereafter the GUI and driver can access the Fundelete Bin files without interfering with each other through the use of the shared mutex.
  • Enumerating the contents of a directory from within a driver. Fundelete must honor the Recycle Bin's size setting so it must dynamically calculate the size of a Bin (the size of all the files it contains).
  • How a filter driver can both stall IRPs headed to a file system, and create and dispatch new IRPs before completing an original request. This highlights the use of STATUS_PENDING and STATUS_MORE_PROCESSING_REQUIRED as return codes.
  • Dynamically determining the SID of a user from within its driver when Fundelete must store a file in a NTFS recycle bin.
Obtaining the Current SID in a Driver One technique that is of particular interest for developers is Fundelete's method for determining the SID of the user that is performing a file system operation. This is acommplished in several steps. First, Fundelete references the current access token, obtaining a pointer to its object body:

   completeContext->Token=PsReferencePrimaryToken(PsGetCurrentProcess());

The next step is for it to obtain a handle to the token object, because token query operations are handle-based. Fundelete accomplishes this through the use of an undocumented API, ObOpenObjectByPointer, that will take an object and create a handle for it in the currently executing process:

   ntStatus=ObOpenObjectByPointer( CompleteContext->Token,
                  0, NULL, TOKEN_QUERY, NULL,
                  KernelMode, &tokenHandle );
   ObDereferenceObject( CompleteContext->Token );

After the handle is returned Fundelete can query the token using the NtQueryInformationToken native API. This function is the basis for the Win32-equivalent, GetInformationToken, so determining its parameters and their formats is straight-forward. Definitions from the Win32 header files are included in Fundelete's header so that Fundelete can perform a TokenUser query on the token, which returns the token's user information including the SID.

   tokenInfoBuffer=(PTOKEN_USER) ExAllocatePool( NonPagedPool, requiredLength );
   ntStatus=NtQueryInformationToken( tokenHandle,
                  TokenUser, tokenInfoBuffer,
                  requiredLength, &requiredLength );
   ZwClose( tokenHandle );

The final step Fundelete performs is to convert the binary representation of the SID into a textual representation. Another undocumented API, RtlConvertSidToUnicodeString, performs this.

   memset( sidStringBuffer, 0, sizeof(sidStringBuffer ));
   sidString.Buffer=(PWCHAR) sidStringBuffer;
   sidString.MaximumLength=sizeof(sidStringBuffer);
   ntStatus=RtlConvertSidToUnicodeString( &sidString, tokenInfoBuffer->User.Sid, FALSE );

Download Fundelete (894KB)

Download Fundelete Undelete.c Source Code (13KB)