| 
 | 
 
很多时候,为了保护商业秘密,一些文件仅仅许可出现一次,就必须删除。 
但是windows的删除是不完善的,可以通过回收站找回,即使windows的彻底删除,也不是彻底删除。也可以通过数据恢复软件找回, 
我们如何实现彻底删除,用二进制数据填充磁盘,来彻底清除相关数据呢 
我们来亲身实践360自带的功能。 
详细类源码如下,请见源码分析,安全删除NTFS file:- #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 ) 
 - {
 -         HANDLE        hFile;
 -         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 TCHAR        volumeName[] = _T("\\\\.\\A:");
 -         static TCHAR        volumeRoot[] = _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)
 - {
 -         char        filename[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 发表于2011-12-15 7:53:30 原文链接  
 
 |   
 
 
 
 |