Elimina archivo o directorio

Elimina un archivo específico, o más importante, una carpeta/directorio con todo su contenido (sub-carpetas y archivos).
NO elimina archivos que esté en uso actualmente por una aplicación externa.



#if !defined(KILLFOLDER_H__)
#define            KILLFOLDER_H__

//includes
#include <rc_class/msgbox.h>
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

//Atributos de carpetas.
#define FOLDER_NORMAL                 (FILE_ATTRIBUTE_DIRECTORY)
#define FOLDER_WINSYS                  (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN)
#define FOLDER_READONLY              (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_READONLY)
#define FOLDER_HIDDEN                   (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_HIDDEN)
#define FOLDER_NOTMOVE               (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_HIDDEN)
#define FOLDER_COMPRESSED         (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_COMPRESSED)
#define FOLDER_TEMP                      (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_TEMPORARY)

//Mensajes de errores.
#define MSG_CAPTION                                  "A ocurrido un error"
//#define MSG_ERROR_MTX               "Se ha superado el máximo de 2000 carpetas. Algunos archivos se han eliminado."
#define MSG_ERROR_HANDLE           "La dirección no es válida:\n%s"
#define MSG_ERROR_FILE                 "El archivo %s está siendo utilizado por una aplicación.\nNo se puede continuar."

//propiedades
#define ALLFILES "\\*.*"         //Atributo: todos los archivos.
#define            ROOTBACK ".."                       //Carpeta superior.No raiz.
//#define MTX_SIZE 2000                    //Máximo tamaño de carpetas almacenadas.



/*
*           'CKillFolder' - Definicion de la clase.-
*/
class CKillFolder
{
private:
            HWND m_hWnd;
public:
            //int m_iPos_Mtx;
            int  Run(char*);
            CKillFolder(HWND hWndParent) {m_hWnd = hWndParent;};
};

/*
*           'Run' - Inicia el proceso de eliminación.
*           En ésta función se resaltan 5 bloques: A,B,C,D,E.-
*/
int CKillFolder::Run(char* lpszInitPath)
{
            HANDLE                                  hFile;                                      //Controlador del archivo.
            BOOL                          bNextFile = true;         //Continuar buscando?.
            WIN32_FIND_DATA tdataFind;                                    //Estructura para FindFirstFile.
            string                           lpszTemp;                               //template class.
            vector<string> lpszDirectory;              //template class.
            DWORD                                   dwType;                                             //tipo de archivo.
            INT                                          iPos;                                       //posición en lpszDirectory.

            // BLOQUE A: Detecta si es archivo o carpeta.
            dwType = GetFileAttributes(lpszInitPath);
            if(dwType != (dwType | FILE_ATTRIBUTE_DIRECTORY) )
            {
                        //Quita el atributo del archivo.
                        SetFileAttributes(lpszInitPath ,(DWORD)0);
                        //Elimina el archivo.
                        if(!DeleteFile(lpszInitPath))
                                   {
                                               MsgOut(m_hWnd,MB_ICONEXCLAMATION,MSG_ERROR_FILE,lpszInitPath);
                                               return 0;
                                   }
                        return 1;
            }
           
            // BLOQUE B: Inicia la búsqueda de sub carpetas.
            lpszDirectory.push_back(lpszInitPath);
            lpszDirectory[0] = lpszDirectory[0] + ALLFILES;

            iPos = 0;         
            while(iPos < lpszDirectory.size() )
            {
                        hFile = FindFirstFile((char*)lpszDirectory[iPos].c_str() ,&tdataFind);
                        if(hFile == INVALID_HANDLE_VALUE)
                        {
                                    MsgOut(m_hWnd,MB_ICONEXCLAMATION,MSG_CAPTION,MSG_ERROR_HANDLE,lpszDirectory[iPos].c_str());
                                   FindClose(hFile);
                                   return 0;
                        }
                        while((TRUE) == bNextFile)
                        {
                                   bNextFile = FindNextFile(hFile,&tdataFind);
                                   if(bNextFile && strcmp(tdataFind.cFileName,ROOTBACK))
                                   {
                                               switch(tdataFind.dwFileAttributes)
                                               {
                                               // BLOQUE C: Almacena nombre de sub carpeta.
                                               case FOLDER_NORMAL:
                                               case FOLDER_HIDDEN:
                                               case FOLDER_WINSYS:
                                               case FOLDER_READONLY:
                                               case FOLDER_COMPRESSED:
                                               case FOLDER_TEMP:
                                               case FOLDER_NOTMOVE:
                                                           lpszTemp = lpszDirectory[iPos].substr(0,lpszDirectory[iPos].length()-3)  + tdataFind.cFileName + ALLFILES;
                                                           lpszDirectory.push_back(lpszTemp);
                                                           break;
                                               default:
                                                           // BLOQUE D: Elimina el archivo.
                                                           lpszTemp = lpszDirectory[iPos].substr(0,lpszDirectory[iPos].length()-3) + tdataFind.cFileName;
                                                           SetFileAttributes((LPCTSTR)lpszTemp.c_str() ,(DWORD)0);
                                                           if(!DeleteFile((LPCTSTR)lpszTemp.c_str()))
                                                           {
                                                                       MsgOut(m_hWnd,MB_ICONEXCLAMATION,MSG_ERROR_FILE,tdataFind.cFileName);
                                                                       FindClose(hFile);
                                                                       return 0;
                                                           }
                                               break;
                                                                                 
                                               }
                                   }
                        }
                        FindClose(hFile);
                        bNextFile = true;
                        iPos = iPos + 1;
            }
            // BLOQUE E: Elimina sub carpetas encontradas en bloque C.
            while(iPos > 0)
            {
                        iPos = iPos - 1;
                        lpszTemp = lpszDirectory[iPos].substr(0,lpszDirectory[iPos].length()-4);
                        RemoveDirectory((char*)lpszTemp.c_str());
            }
            return 1;
}
#endif//_KILLFOLDER_

/*
*           End for "$id: killfolder.h,v 1.7 25/01/2007 $"

*/