|
很多时候,为了保护商业秘密,一些文件仅仅许可出现一次,就必须删除。
但是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 原文链接
|
|