clearbuffer

来源:互联网 发布:vim写c语言 编辑:程序博客网 时间:2024/06/09 15:00

#include "stdafx.h"

 

#include "SecureDelNTFS.h"

#include <time.h>

 

 

#ifdef _DEBUG

#undef THIS_FILE

static char THIS_FILE[]=__FILE__;

#define new DEBUG_NEW

#endif

#define OVERWRITE_PASSES 1

#define BUFFER_SIZE 1024

//////////////////////////////////////////////////////////////////////

// Construction/Destruction

//////////////////////////////////////////////////////////////////////

CSecureDelNTFS::CSecureDelNTFS()

{

       Recurse = true;

       ZapFreeSpace = true;

       CleanCompressedFiles = FALSE;

       NumPasses = 1;

       FilesFound = 0;

       firstCall = false;

       deleteDirectories = false;

       //  以系统时间为种子构造随机数

       srand( (unsigned)time( NULL ));

}

 

CSecureDelNTFS::~CSecureDelNTFS()

{

 

}

 

/////////////////////////////////////////////////////////////////////////////

// 函数名:  OverwriteFileName( PTCHAR FileName, PTCHAR LastFileName )

// 参数列表:PTCHAR FileName

//                   PTCHAR LastFileName

// 函数功能:该函数的功能是安全删除文件名

/////////////////////////////////////////////////////////////////////////////

VOID CSecureDelNTFS::OverwriteFileName( PTCHAR FileName, PTCHAR LastFileName )

{

       TCHAR          newName[MAX_PATH];

       PTCHAR        lastSlash;

       DWORD        i, j, index;

 

       _tcscpy( LastFileName, FileName );

       lastSlash = _tcsrchr( LastFileName, _T('\\'));

       index = (lastSlash - LastFileName)/sizeof(TCHAR);

       //  产生一个新的名称

       CString sz="abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz";

       if(index>125)

              sz=sz.Left((130-(index-125)));

       CString NewName=((CString) LastFileName).Left(index)+"\\"+CryptString(sz);

       sprintf(LastFileName,"%s",NewName);

       MoveFile( FileName, NewName );

      

       _tcscpy( LastFileName, NewName );

       lastSlash = _tcsrchr( LastFileName, _T('\\'));

       index = (lastSlash - LastFileName)/sizeof(TCHAR);

       int k=_tcsclen( LastFileName );

 

       _tcscpy( newName, NewName );

       int number=rand()*20/32767+2;

       for( i = 0; i < number; i++ )

       {

              //     用随机产生的符号替换文件名中非'.'符号

              for( j = index+1 ; j < _tcsclen( LastFileName ); j++ )

              {

                     if( LastFileName[j] != _T('.'))      

                     {

                            int random=int((rand()*74/32767));

                            if(random>=10 && random<=16)random=17;

                            if(random>=43 && random<=48)random=49;

                            newName[j] = (TCHAR) random + _T('0'); 

                     }

              }

              //     用产生的新名称重命名

              MoveFile( LastFileName, newName );

              _tcscpy( LastFileName, newName );

       }

}

 

/////////////////////////////////////////////////////////////////////////////

// 函数名:  OverwriteDirectoryName( PTCHAR FileName, PTCHAR LastFileName )

// 参数列表:PTCHAR FileName

//                   PTCHAR LastFileName

// 函数功能:该函数的功能是安全删除文件名

/////////////////////////////////////////////////////////////////////////////

VOID CSecureDelNTFS::OverwriteDirectoryName( PTCHAR FileName, PTCHAR LastFileName )

{

       TCHAR          newName[MAX_PATH];

       PTCHAR        lastSlash;

       DWORD        i, j, index;

 

       _tcscpy( LastFileName, FileName );

       lastSlash = _tcsrchr( LastFileName, _T('\\'));

       index = (lastSlash - LastFileName)/sizeof(TCHAR);

       //  产生一个新的名称

       CString NewName=((CString) LastFileName).Left(index)+"\\"+CryptString("abcdefgh.XYZ");

       sprintf(LastFileName,"%s",NewName);

       MoveFile( FileName, NewName );

      

       _tcscpy( LastFileName, NewName );

       lastSlash = _tcsrchr( LastFileName, _T('\\'));

       index = (lastSlash - LastFileName)/sizeof(TCHAR);

       int k=_tcsclen( LastFileName );

 

       _tcscpy( newName, NewName );

       int number=rand()*20/32767+2;

       for( i = 0; i < number; i++ )

       {

              //     用随机产生的符号替换文件名中非'.'符号

              for( j = index+1 ; j < _tcsclen( LastFileName ); j++ )

              {

                     if( LastFileName[j] != _T('.'))      

                     {

                            int random=int((rand()*74/32767));

                            if(random>=10 && random<=16)random=17;

                            if(random>=43 && random<=48)random=49;

                            newName[j] = (TCHAR) random + _T('0'); 

                     }

              }

              //     用产生的新名称重命名

              MoveFile( LastFileName, newName );

              _tcscpy( LastFileName, newName );

       }

}

/////////////////////////////////////////////////////////////////////////////

// 函数名:  CryptString(CString string)

// 参数列表:CString string

// 函数功能:该函数的功能是根据已有的字符串产生一个加密的字符串

/////////////////////////////////////////////////////////////////////////////

CString CSecureDelNTFS::CryptString(CString string)

{

       TCHAR          FirstString[MAX_PATH];     

       _tcscpy( FirstString, string );

       srand( (unsigned)time( NULL ) );

       //     产生一个随机字符替换字符串中非'.'字符

       for( int j = 0 ; j < _tcsclen( FirstString ); j++ )

       {

              if( FirstString[j] != _T('.'))          

              {

                     int random=int((rand()*74/32767));

                     if(random>=10 && random<=16)random=17;

                     if(random>=43 && random<=48)random=49;

                     FirstString[j] = (TCHAR) random + _T('0'); 

              }

       }

       return (CString) FirstString;

}

 

/////////////////////////////////////////////////////////////////////////////

// 函数名:  SecureOverwrite( HANDLE FileHandle, DWORD Length )

// 参数列表:HANDLE FileHandle

//                   DWORD Length

// 函数功能:该函数的功能是安全删除文件

/////////////////////////////////////////////////////////////////////////////

BOOLEAN CSecureDelNTFS::SecureOverwrite( HANDLE FileHandle, DWORD Length )

{

#define CLEANBUFSIZE 65536

       static PBYTE  cleanBuffer[3];

       static BOOLEAN    buffersAlloced = FALSE;

 

       DWORD        i, j, passes;

       DWORD        bytesWritten, bytesToWrite, totalWritten;

       LONG            seekLength;

       BOOLEAN            status;

 

       //     分配执行清除操作所需的缓冲区

       if( !buffersAlloced )

       {

              //     设置系统时间为随机数种子

              srand( (unsigned)time( NULL ) );

              for( i = 0; i < 3; i++ )

              {

                     //  设置清除缓冲区内容

                     cleanBuffer[i] = (unsigned char *)VirtualAlloc( NULL, CLEANBUFSIZE, MEM_COMMIT, PAGE_READWRITE );

                     if( !cleanBuffer[i] )

                     {

                            for( j = 0; j < i; j++ )

                            {

                                   VirtualFree( cleanBuffer[j], 0, MEM_RELEASE );

                            }

                            return FALSE;

                     }

                     switch( i )

                     {

 

                     case 0:

                            // 缓冲区内容为0

                            break;

                     case 1:

                            // 缓冲区内容为0 - 0xFF

                            memset( cleanBuffer[i], 0x00, CLEANBUFSIZE );

                            break;

                     case 2:

                            // 缓冲区内容为随机值

                            for( j = 0; j < CLEANBUFSIZE; j++ ) cleanBuffer[i][j] = (BYTE) rand();

                            break;

                     }

              }    

              buffersAlloced = TRUE;

       }

       // 执行覆盖操作

       seekLength = (LONG) Length;

       for( passes = 0; passes < NumPasses; passes++ )

       {

              if( passes != 0 )

              {

                     // 将指针设置为最开始

                     SetFilePointer( FileHandle, -seekLength, NULL, FILE_CURRENT );

              }

              for( i = 0; i < 2; i++ )

              {

                     // 将指针设置为最开始

                     if( i != 0 )

                     {

                            SetFilePointer( FileHandle, -seekLength, NULL, FILE_CURRENT );

                     }

                     // 循环并覆盖

                     bytesToWrite = Length;

                     totalWritten = 0;

                     while( totalWritten < Length )

                     {

                            bytesToWrite = Length - totalWritten;

                            if( bytesToWrite > CLEANBUFSIZE ) bytesToWrite = CLEANBUFSIZE;

 

                            status = WriteFile( FileHandle, cleanBuffer[i], bytesToWrite, &bytesWritten, NULL );

                            if( !status ) return FALSE;

                            totalWritten += bytesWritten;

                     }

              }

       }

       return TRUE;

}

 

/////////////////////////////////////////////////////////////////////////////

// 函数名:  SecureDelete( PTCHAR FileName, DWORD FileLengthHi,DWORD FileLengthLo )

// 参数列表:PTCHAR FileName

//                   DWORD FileLengthHi

//                   DWORD FileLengthLo

//                   DWORD Length

// 函数功能:该函数的功能是安全删除指定的文件

/////////////////////////////////////////////////////////////////////////////

VOID CSecureDelNTFS::SecureDelete( PTCHAR FileName, DWORD FileLengthHi,

                                   DWORD FileLengthLo )

{

       HANDLEhFile;

       ULONGLONG bytesToWrite, bytesWritten;

       ULARGE_INTEGER fileLength;

       TCHAR   lastFileName[MAX_PATH];

       //     首先以覆盖的模式打开文件

       hFile = CreateFile( FileName, GENERIC_WRITE,

                                          FILE_SHARE_READ|FILE_SHARE_WRITE,

                                          NULL, OPEN_EXISTING, FILE_FLAG_WRITE_THROUGH, NULL );

       if( hFile == INVALID_HANDLE_VALUE )

              return;

       // 如果文件的长度不为零,则将文件所占的所有簇填入0

       if( FileLengthLo || FileLengthHi )

       {

              //  找文件的后一簇

              FileLengthLo--;

              if( FileLengthLo == (DWORD) -1 && FileLengthHi ) FileLengthHi--;

              SetFilePointer( hFile, FileLengthLo, (long *) &FileLengthHi, FILE_BEGIN );

              // 在文件中填入0

              if( !SecureOverwrite( hFile, 1 ))

              {

                     CloseHandle( hFile );

                     return;

              }

              // 回到文件的头部,处理文件剩下的部分

              SetFilePointer( hFile, 0, NULL, FILE_BEGIN );

              fileLength.LowPart = FileLengthLo;

              fileLength.HighPart = FileLengthHi;

              bytesWritten = 0;

              while( bytesWritten < fileLength.QuadPart )

              {

                     bytesToWrite = min( fileLength.QuadPart - bytesWritten, 65536 );

                     if( !SecureOverwrite( hFile, (DWORD) bytesToWrite ))

                     {

                            CloseHandle( hFile );

                            return;

                     }

                     bytesWritten += bytesToWrite;

              }

       }

       //  完成后关闭文件

       CloseHandle( hFile );

       //  重命名文件

       OverwriteFileName( FileName, lastFileName );

       //  删除文件

       if( !DeleteFile( lastFileName ) )

              return;

}

 

/////////////////////////////////////////////////////////////////////////////

// 函数名:  BOOLEAN CSecureDelNTFS::ScanFile( HANDLE VolumeHandle,  DWORD ClusterSize,

//                            HANDLE FileHandle, PBOOLEAN ReallyCompressed, PBOOLEAN ZappedFile )

// 参数列表:ANDLE VolumeHandle

//           DWORD ClusterSize

//           HANDLE FileHandle

//           PBOOLEAN ReallyCompressed

//           PBOOLEAN ZappedFilePTCHAR

// 函数功能:该函数的功能是当NTFS卷是压缩、加密时调用进行文件扫描

/////////////////////////////////////////////////////////////////////////////

BOOLEAN CSecureDelNTFS::ScanFile( HANDLE VolumeHandle,  DWORD ClusterSize,

                              HANDLE FileHandle, PBOOLEAN ReallyCompressed, PBOOLEAN ZappedFile )

{

       DWORD                                    status;

       int                                              i;

       IO_STATUS_BLOCK                          ioStatus;

       ULONGLONG                                   startVcn, prevVcn;

       LARGE_INTEGER                      clusterOffset;

       ULONGLONG                                   endOfPrevRun;

       PGET_RETRIEVAL_DESCRIPTOR     fileMappings;

       ULONGLONG                                   fileMap[ FILEMAPSIZE ];

       int                                              lines = 0;

       // 假设文件位于MFT记录中

       *ReallyCompressed = FALSE;

       *ZappedFile = FALSE;

       startVcn = 0;

       endOfPrevRun = LLINVALID;

       fileMappings = (PGET_RETRIEVAL_DESCRIPTOR) fileMap;

       while( !(status = NtFsControlFile( FileHandle, NULL, NULL, 0, &ioStatus,

                                          FSCTL_GET_RETRIEVAL_POINTERS,

                                          &startVcn, sizeof( startVcn ),

                                          fileMappings, FILEMAPSIZE * sizeof(ULONGLONG) ) ) ||

                      status == STATUS_BUFFER_OVERFLOW ||

                      status == STATUS_PENDING )

       {

              // 如果操作正在进行,则等待完成

              if( status == STATUS_PENDING )

              {

                     WaitForSingleObject( FileHandle, INFINITE );

                     // 获取状态参数

                     if( ioStatus.Status != STATUS_SUCCESS && ioStatus.Status != STATUS_BUFFER_OVERFLOW )

                     {

                            return ioStatus.Status == STATUS_SUCCESS;

                     }

              }

              startVcn = fileMappings->StartVcn;

              prevVcn  = fileMappings->StartVcn;

              for( i = 0; i < (ULONGLONG) fileMappings->NumberOfPairs; i++ )

              {    

                     if( fileMappings->Pair[i].Lcn != LLINVALID )

                     {

                            // 压缩模式

                            *ReallyCompressed = TRUE;

                            // 覆盖所在的簇

                            if( VolumeHandle != INVALID_HANDLE_VALUE )

                            {

                                   clusterOffset.QuadPart = fileMappings->Pair[i].Lcn * ClusterSize;

                                   SetFilePointer( VolumeHandle, clusterOffset.LowPart,

                                                               &clusterOffset.HighPart, FILE_BEGIN );

                                   if( !SecureOverwrite( VolumeHandle,

                                                               ClusterSize * (DWORD) (fileMappings->Pair[i].Vcn - startVcn) ))

                                          return TRUE;

                            }

                            else

                                   return TRUE; 

                     }

                     startVcn = fileMappings->Pair[i].Vcn;

              }

              if( !status ) break;

       }

       if( status == STATUS_SUCCESS ) *ZappedFile = TRUE;

       return status == STATUS_SUCCESS;

}

 

/////////////////////////////////////////////////////////////////////////////

// 函数名:  SecureDeleteCompressed( PTCHAR FileName )

// 参数列表:PTCHAR FileName

// 函数功能:该函数的功能是删除压缩磁盘中的文件

/////////////////////////////////////////////////////////////////////////////

BOOLEAN CSecureDelNTFS::SecureDeleteCompressed( PTCHAR FileName )

{

       HANDLE               hFile;

       BOOLEAN                   reallyCompressed = FALSE;

       BOOLEAN                   zappedFile = FALSE;

       TCHAR                 lastFileName[MAX_PATH];

       static TCHARvolumeName[] = _T("\\\\.\\A:");

       static TCHARvolumeRoot[] = _T("A:\\");

       static HANDLE      hVolume = INVALID_HANDLE_VALUE;

       static DWORD       clusterSize;

       DWORD               sectorsPerCluster, bytesPerSector, freeClusters, totalClusters;

       // 打开卷

       if( hVolume == INVALID_HANDLE_VALUE )

       {

              volumeName[4] = FileName[0];

              hVolume = CreateFile( volumeName, GENERIC_READ|GENERIC_WRITE,

                                                 FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING,

                                                 0, 0 );

              volumeRoot[0] = FileName[0];

              GetDiskFreeSpace( volumeRoot, §orsPerCluster, &bytesPerSector,

                                          &freeClusters, &totalClusters );

              clusterSize = bytesPerSector * sectorsPerCluster;

       }

       // 打开文件

       hFile = CreateFile( FileName, GENERIC_READ,

                                          0,NULL, OPEN_EXISTING, 0, NULL );

       if( hFile == INVALID_HANDLE_VALUE )

              return TRUE;

       // 确定文件的位置

       if( !ScanFile( hVolume, clusterSize, hFile,

                     &reallyCompressed, &zappedFile ))

       {

 

              CloseHandle( hFile );

              return TRUE;

       }

       // 关闭文件

       CloseHandle( hFile );

       if( reallyCompressed )

       {

              // 重新命名文件名

              OverwriteFileName( FileName, lastFileName );

              //  文件长度修改为0

              FILE *fp=fopen(lastFileName,"w");

              fclose(fp);

              //  删除文件

              if( !DeleteFile( lastFileName ))

              {

                     MoveFile( lastFileName, FileName );

                     return TRUE;

              }

              // 如果不能直接覆盖文件的簇,则通过清除磁盘的自由空间来覆盖

              if( !zappedFile ) CleanCompressedFiles = TRUE;

       }

       return reallyCompressed;

}

 

/////////////////////////////////////////////////////////////////////////////

// 函数名:  ProcessFile( PWIN32_FIND_DATA FindData, TCHAR *FileName )

// 参数列表:PWIN32_FIND_DATA FindData

//                   TCHAR *FileName

// 函数功能:该函数的功能是处理文件的删除

/////////////////////////////////////////////////////////////////////////////

VOID CSecureDelNTFS::ProcessFile( PWIN32_FIND_DATA FindData, TCHAR *FileName )

{

       // 如果是目录的删除,则直接返回

       if( FindData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) return;

       FilesFound++;

       // 如果文件是压缩的

       if( FindData->dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED ||

              FindData->dwFileAttributes & FILE_ATTRIBUTE_ENCRYPTED  ||

              FindData->dwFileAttributes & FILE_ATTRIBUTE_SPARSE_FILE )

       {

              // 处理压缩磁盘中的文件

              if( SecureDeleteCompressed( FileName )) return;

       }

       // 删除常规(非压缩、非加密磁盘)文件

       SecureDelete( FileName, FindData->nFileSizeHigh,

                                                 FindData->nFileSizeLow );

}

 

/////////////////////////////////////////////////////////////////////////////

// 函数名:  ProcessDirectory( TCHAR *PathName, TCHAR *SearchPattern )

// 参数列表:TCHAR *PathName

//                   TCHAR *SearchPattern

// 函数功能:该函数的功能是处理目录的删除

/////////////////////////////////////////////////////////////////////////////

void CSecureDelNTFS::ProcessDirectory( TCHAR *PathName, TCHAR *SearchPattern )

{

       TCHAR                 subName[MAX_PATH], fileSearchName[MAX_PATH], searchName[MAX_PATH];

       HANDLE               dirHandle, patternHandle;

       WIN32_FIND_DATA foundFile;

       TCHAR                 lastFileName[MAX_PATH];

       // 遍历所有的文件和目录

       if( firstCall )

       {

              if( _tcsrchr( PathName, '*' ) )

              {

            if( _tcsrchr( PathName, '\\' ) )

                     {

                _stprintf( SearchPattern, _tcsrchr( PathName, '\\' )+1 );

                _tcscpy( searchName, PathName );

                _tcscpy( _tcsrchr( searchName, '\\')+1, _T("*.*") );

                            if( !_tcscmp( SearchPattern, _T("*.*")) || !_tcscmp( SearchPattern, _T("*")))

                            {

                                   deleteDirectories = TRUE;

                            }

            }

                     else

                     {

                _stprintf( SearchPattern, PathName );

                _tcscpy( searchName, PathName );

            }

            _stprintf( fileSearchName, _T("%s"), PathName );

              }

              else

              {

                     _stprintf( SearchPattern, _T("*.*") );

                     _stprintf( searchName, _T("%s"), PathName );

            _stprintf( fileSearchName, _T("%s"), PathName );

                     deleteDirectories = TRUE;

              }

       }

       else

       {

              _stprintf( searchName, _T("%s\\*.*"), PathName );

              _stprintf( fileSearchName, _T("%s\\%s"), PathName, SearchPattern );

       }

       // 处理所有的文件

       if( (patternHandle = FindFirstFile( fileSearchName, &foundFile )) !=

              INVALID_HANDLE_VALUE  )

       {

              do

              {

                     if( _tcscmp( foundFile.cFileName, _T(".") ) &&_tcscmp( foundFile.cFileName, _T("..") ))

                     {

                            _tcscpy( subName, searchName );

                            if( _tcsrchr( subName, '\\' ) )

                                   _tcscpy( _tcsrchr( subName, '\\')+1, foundFile.cFileName );

                            else

                                   _tcscpy( subName, foundFile.cFileName );

                            // 处理文件

                            ProcessFile( &foundFile, subName );

                     }

              }

              while( FindNextFile( patternHandle, &foundFile ));

              FindClose( patternHandle );

       }

       // 进行递归删除

       if( Recurse )

       {

        if( firstCall && !_tcsrchr( searchName, L'\\') )

              {

            if( _tcsrchr( searchName, L'*' ))

                     {

 

                if( (dirHandle = FindFirstFile( _T("*.*"), &foundFile )) == INVALID_HANDLE_VALUE)

                    return;

            }

                     else

                     {

 

                if( (dirHandle = FindFirstFile( searchName, &foundFile )) == INVALID_HANDLE_VALUE)

                    return;

            }

        }

              else

              {

            if( (dirHandle = FindFirstFile( searchName, &foundFile )) == INVALID_HANDLE_VALUE)

                return;

        }

        firstCall = FALSE;

              do

              {

 

                     if( (foundFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&

                            _tcscmp( foundFile.cFileName, _T(".") ) &&

                            _tcscmp( foundFile.cFileName, _T("..") ))

                     {

 

                            _tcscpy( subName, searchName );

                            if( _tcsrchr( subName, '\\' ) )

                                   _tcscpy( _tcsrchr( subName, '\\')+1, foundFile.cFileName );

                            else

                                   _tcscpy( subName, foundFile.cFileName );

                            // 处理目录

                            ProcessDirectory( subName, SearchPattern );

                            // 删除目录

                            if( deleteDirectories )

                            {

                                   //  重新命名文件名

                                   OverwriteDirectoryName( subName, lastFileName );

                                   SetFileAttributes(lastFileName,FILE_ATTRIBUTE_NORMAL);

                                   RemoveDirectory( lastFileName );

                            }

                     }

              }

              while( FindNextFile( dirHandle, &foundFile ));

              FindClose( dirHandle );

       }

}

 

/////////////////////////////////////////////////////////////////////////////

// 函数名:  CleanFreeSpace( PTCHAR DrivePath )

// 参数列表:PTCHAR DrivePath

// 函数功能:该函数的功能是清除磁盘的自由空间

/////////////////////////////////////////////////////////////////////////////

BOOLEAN CSecureDelNTFS::CleanFreeSpace( PTCHAR DrivePath )

{

       TCHAR          tempFileName[MAX_PATH];

       ULARGE_INTEGER bytesAvail, totalBytes, freeBytes;

       DWORD        sectorsPerCluster, bytesPerSector, totalClusters, freeClusters;

       ULONGLONG       tempSize = 0;

       HANDLE        hTempFile;

       BOOLEAN            createdFile;

       DWORD        cleanSize, mftFilesCreated;

       DWORD        prevSize;

       CString          strText;

 

       if( DrivePath[1] != ':' )

              return FALSE;

       // 磁盘分区路径

       DrivePath[3] = 0;

       if( !GetDiskFreeSpace( DrivePath, §orsPerCluster, &bytesPerSector,

              &freeClusters, &totalClusters ))

              return FALSE;

#if UNICODE

       if( !(pGetDiskFreeSpaceEx = (int (__stdcall *)(const char *,union _ULARGE_INTEGER *,union _ULARGE_INTEGER *,union _ULARGE_INTEGER *)) GetProcAddress( GetModuleHandle( _T("kernel32.dll") ),

                                                                             "GetDiskFreeSpaceExW" ))) {

#else

       if( !(pGetDiskFreeSpaceEx = (int (__stdcall *)(const char *,union _ULARGE_INTEGER *,union _ULARGE_INTEGER *,union _ULARGE_INTEGER *)) GetProcAddress( GetModuleHandle( _T("kernel32.dll") ),

                                                                             "GetDiskFreeSpaceExA" ))) {

#endif

              bytesAvail.QuadPart = sectorsPerCluster * freeClusters * bytesPerSector;

        freeBytes.QuadPart = bytesAvail.QuadPart;

       }

       else

       {

              if( !pGetDiskFreeSpaceEx( DrivePath, &bytesAvail, &totalBytes, &freeBytes ))

                     return FALSE;

       }

 

       if( bytesAvail.QuadPart != freeBytes.QuadPart )

              return FALSE;

       _stprintf( tempFileName, _T("%sSDELTEMP"), DrivePath );

       hTempFile = CreateFile( tempFileName, GENERIC_WRITE,

                                   0, NULL, CREATE_NEW,

                                   FILE_FLAG_NO_BUFFERING|FILE_FLAG_SEQUENTIAL_SCAN|

                                   FILE_FLAG_DELETE_ON_CLOSE|FILE_ATTRIBUTE_HIDDEN, NULL );

       if( hTempFile == INVALID_HANDLE_VALUE )

              return FALSE;

       // 分配清除缓冲区

       cleanSize = sectorsPerCluster * bytesPerSector * 128;

       // 增大簇的容量直到超过极限

       while( cleanSize > bytesPerSector * sectorsPerCluster )

       {

              if( SecureOverwrite( hTempFile, cleanSize ))

              {

                     tempSize += cleanSize;

              }

              else

              {

                     cleanSize -= bytesPerSector * sectorsPerCluster;

              }

       }

       // 最后存在一个小于一个完整簇的空间,利用另外一个临时文件覆盖

       _stprintf( tempFileName, _T("%sSDELTEMP1"), DrivePath );

       hTempFile = CreateFile( tempFileName, GENERIC_WRITE,

                                   0, NULL, CREATE_NEW,

                                   FILE_FLAG_SEQUENTIAL_SCAN|FILE_FLAG_DELETE_ON_CLOSE|

                                   FILE_ATTRIBUTE_HIDDEN|FILE_FLAG_WRITE_THROUGH, NULL );

 

       if( hTempFile != INVALID_HANDLE_VALUE )

       {

              while( cleanSize )

              {

                     if( SecureOverwrite( hTempFile, cleanSize ))

                     {

                            tempSize += cleanSize;

                     }else

                     {

                            cleanSize--;

                     }

              }

       }

 

       if( ZapFreeSpace )

       {

              mftFilesCreated = 0;

              // 最大的MFT 记录大小

              prevSize = 4096;

              while( 1 )

              {

                     _stprintf( tempFileName, _T("%sSDELMFT%06d"), DrivePath, mftFilesCreated++ );

                     hTempFile = CreateFile( tempFileName, GENERIC_WRITE,

                                                 0, NULL, CREATE_NEW,

                                                 FILE_FLAG_SEQUENTIAL_SCAN|FILE_FLAG_DELETE_ON_CLOSE|

                                                 FILE_ATTRIBUTE_HIDDEN, NULL );

                     if( hTempFile == INVALID_HANDLE_VALUE )

                     {

 

                            break;

                     }

                     cleanSize = prevSize;

                     createdFile = FALSE;

                     while( cleanSize )

                     {

                            if( !SecureOverwrite( hTempFile, cleanSize ))

                            {

                                   cleanSize--;

                            }

                            else

                            {

                                   prevSize = cleanSize;

                                   createdFile = TRUE;

                                   tempSize += cleanSize;

                            }

                     }    

                     if( !createdFile ) break;

              }

       }

       return TRUE;

}

 

/////////////////////////////////////////////////////////////////////////////

// 函数名:  LocateNativeEntryPoints()

// 参数列表:

// 函数功能:该函数的功能是定位NTDLL的入口点

/////////////////////////////////////////////////////////////////////////////

VOID CSecureDelNTFS::LocateNativeEntryPoints()

{

       // 如果当前的Windows版本是Win9x,则直接返回

       if( GetVersion() >= 0x80000000) return;

    // 装入所需的NTDLL入口点

       if( !(NtFsControlFile = (unsigned int (__stdcall *)(void *,void *,void (__cdecl *)(void *,struct _IO_STATUS_BLOCK *,unsigned long),void *,struct _IO_STATUS_BLOCK *,

              unsigned long,void *,unsigned long,void *,unsigned long)) GetProcAddress( GetModuleHandle(_T("ntdll.dll")),

                     "NtFsControlFile" )) )

       {

              AfxMessageBox("Could not find NtFsControlFile entry point in NTDLL.DLL",MB_OK | MB_ICONERROR);

              exit(1);

       }

       if( !(RtlNtStatusToDosError = (unsigned long (__stdcall *)(unsigned int)) GetProcAddress( GetModuleHandle(_T("ntdll.dll")),

                                                 "RtlNtStatusToDosError" )) )

       {

              AfxMessageBox("Could not find RtlNtStatusToDosError entry point in NTDLL.DLL",MB_OK | MB_ICONERROR);

              exit(1);

       }

}

 

/////////////////////////////////////////////////////////////////////////////

// 函数名:  WipeFileContent(LPCTSTR pFilePath)

// 参数列表:

// 函数功能:该函数主要用于将需要删除的文件全部清零

/////////////////////////////////////////////////////////////////////////////

BOOL CSecureDelNTFS::WipeFileContent(CString strfilename)

{

       charfilename[MAX_PATH];

       sprintf(filename, "%s", strfilename);

 

       HANDLE hFile = CreateFile(filename, GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,

                                                 NULL, OPEN_ALWAYS, FILE_FLAG_WRITE_THROUGH, NULL);

       if (hFile == INVALID_HANDLE_VALUE)

              return false;

 

       DWORD fileSize = GetFileSize(hFile, 0);

       // 如果文件是空,则直接返回

       if (!fileSize)

       {

              CloseHandle(hFile);

              return false;

       }

 

       DWORD j=0;

 

       for (int passes = 0; passes < OVERWRITE_PASSES; passes++)

       {

              char newStorage[BUFFER_SIZE];

              srand((unsigned)time(NULL));

              if(passes<(OVERWRITE_PASSES-1))

                     FillMemory((void*)newStorage, BUFFER_SIZE, rand() % 255);

              else

                     FillMemory((void*)newStorage, BUFFER_SIZE, 0);

 

              SetFilePointer(hFile, 0, NULL, FILE_BEGIN);

 

              DWORD left = fileSize;

              int write = BUFFER_SIZE;

              DWORD written = 0;

             

              while (left)

              {

                     j=j+1;

                     if (left < BUFFER_SIZE) write = left;

                     BOOL status = WriteFile(hFile, newStorage, write, &written, NULL);

                     if (!status)

                     {

                            CloseHandle(hFile);

                            return false;

                     }

 

                     left -= write;

              }

       }

 

       CloseHandle(hFile);

       return true;

}

 

类中的调用源码如下

 

void CSDeleteNTFSDlg::OnButtonSecuredel()

{

       // TODO: Add your control notification handler code here

       if(m_filename!="")

       {

              //  采用全部清零的方法删除文件的内容

              m_SdelNTFS.WipeFileContent(m_filename);

              //  设置文件的长度为零

              FILE *fp=fopen(m_filename,"w");

              fclose(fp);

              //     删除该文件的文件名   

              TCHAR       searchPattern[MAX_PATH];

              TCHAR          searchPath[MAX_PATH];

              sprintf(searchPath, "%s", m_filename);

              m_SdelNTFS.firstCall = true;

              m_SdelNTFS.deleteDirectories =false;

              m_SdelNTFS.ProcessDirectory( searchPath, searchPattern );          

      

              AfxMessageBox("安全删除完毕!");

              m_filename="";

       }

       UpdateData(false);

      

}

 

 

 


摘自 yincheng01