Self Delete

////////////////////////////////////////////////////////
// SelfDelete() invokes the command interpreter as define by
// the environment variable "COMSPEC".  This varies with the
// OS: Win9x/ME use COMMAND.COM; WinNT/2K/XP use CMD.EXE.
// 
// The module filename (szModule) needs to be converted into
// its short 8.3 name to change any extended unicode chars
// into OEM equivalents.
// 

// SelfDelete() should be called only at the program's exit.
// Make sure all processes/threads have finished and all
// handles are closed before calling the function.
////////////////////////////////////////////////////////

 

// Author: Tony Varnas

#include <windows.h>
#include <shlobj.h>
#include <shellapi.h>

BOOL SelfDelete(void)
{
    SHELLEXECUTEINFO sei;

    TCHAR szModule [MAX_PATH],
        szComspec[MAX_PATH],
        szParams [MAX_PATH];

    // get file path names
    if((GetModuleFileName(0,szModule,MAX_PATH)!=0) &&
            (GetShortPathName(szModule,szModule,MAX_PATH)!=0) &&
            (GetEnvironmentVariable("COMSPEC",szComspec,MAX_PATH)!=0))
    {
        // create comspec parameters
        lstrcpy(szParams,"/c del "); // run a single command to...
        lstrcat(szParams, szModule); // del(ete) module file and...
        lstrcat(szParams, " > nul"); // output results to nowhere

        // set struct members
        sei.cbSize = sizeof(sei);
        sei.hwnd = 0;
        sei.lpVerb = "Open";
        sei.lpFile= szComspec;
        sei.lpParameters = szParams;
        sei.lpDirectory = 0;
        sei.nShow = SW_HIDE;
        sei.fMask = SEE_MASK_NOCLOSEPROCESS;

        // give all CPU cycles to current process
        SetPriorityClass(GetCurrentProcess(),REALTIME_PRIORITY_CLASS);
        SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_TIME_CRITICAL);

        // execute command shell
        if(ShellExecuteEx(&sei))
        {
            // freeze command shell process
            SetPriorityClass(sei.hProcess,IDLE_PRIORITY_CLASS);
            SetProcessPriorityBoost(sei.hProcess,TRUE);

            // notify explorer shell of deletion
            SHChangeNotify(SHCNE_DELETE,SHCNF_PATH,szModule,0);
            return TRUE;
        }
        else
        {
            // otherwise, restore normal priority
            SetPriorityClass(GetCurrentProcess(),NORMAL_PRIORITY_CLASS);
            SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_NORMAL);
        }
    }
    return FALSE;
}

Back to main page