很多时候,为了保护商业秘密,一些文件仅仅许可出现一次,就必须删除。
但是Windows的删除是不完善的,可以通过回收站找回,即使Windows的彻底删除,也不是彻底删除。也可以通过数据恢复软件找回,
我们如何实现彻底删除,用二进制数据填充磁盘,来彻底清除相关数据呢
我们来亲身实践360自带的功能。
详细类源码如下,请见源码分析,安全删除NTFS
#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;
}