📄 scwfnt.c
字号:
if(GetSMOffQueue(vi->OverwriteQueue,&sm,bCleanOver))
{
int retries;
*pbDidOne=TRUE;
retries=0;
do
{
// Move pattern from old end of file to new end of file
RetVal=ClusterNTWipeCluster( vi->hWipe,vi,
0,
sm.Orig,
sm.Size);
retries++;
if(vi->bCancel)
return FALSE;
} while((RetVal==WFE_ALREADYCOMMIT)&&(retries<RETRIES));
// if(RetVal!=WFE_NOERROR)
// StatusMessage(vi,"Error", FALSE);
// else
// StatusMessage(vi,"OK", FALSE);
vi->dwClustersWritten=vi->dwClustersWritten+1;
// if(RetVal!=WFE_NOERROR)
// MessageBox(NULL,"test2","debug",MB_OK);
PutSMOnQueue(vi->MoveBackQueue,&sm);
}
// These steps are followed 200 clusters behind
// in order to assure NTFS has had time to deallocate
// the space
if(GetSMOffQueue(vi->MoveBackQueue,&sm,bCleanBack))
{
int retries;
HANDLE hMoveBack;
*pbDidOne=TRUE;
retries=0;
hMoveBack = CreateFile( sm.name, GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
FILE_FLAG_NO_BUFFERING, 0 );
free(sm.name);
if( hMoveBack != INVALID_HANDLE_VALUE )
{
do
{
RetVal=ClusterNTWipeCluster( hMoveBack,vi,
sm.Vcn,
sm.Orig,
sm.Size);
retries++;
if(vi->bCancel)
{
CloseHandle(hMoveBack);
return FALSE;
}
} while((RetVal==WFE_ALREADYCOMMIT)&&(retries<RETRIES));
CloseHandle(hMoveBack);
}
// if(RetVal!=WFE_NOERROR)
// StatusMessage(vi,"Error", FALSE);
// else
// StatusMessage(vi,"OK", FALSE);
vi->dwClustersWritten=vi->dwClustersWritten+1;
// if(RetVal!=WFE_NOERROR)
// MessageBox(NULL,"test3","debug",MB_OK);
}
return TRUE;
}
// This is the callback provided to our CreateFileList call.
// It will send us every filename on the drive. We'll free
// the links in the list ourselves to cut down on memory
// consumption
BOOL WipeFreeCountCallback(FILELIST *fl,void *pUserValue)
{
VOLINFO *vi;
char szText[MAX_PATH+100];
vi=(VOLINFO *)pUserValue;
if(!fl->IsDirectory)
{
// We'll have to do three cluster moves per file
// original->temp, pattern->original,temp->original
vi->dwClusterCount=vi->dwClusterCount+3;
strcpy(szText,"Scanning disk\n");
strcat(szText,fl->name);
StatusMessage(vi,szText,FALSE);
}
free(fl->name);
free(fl);
return (vi->bCancel);
}
BOOL CountFileClusterMoves(VOLINFO *vi)
{
// For the biggie file
// vi->dwClusterCount=vi->no_of_freeclusters;
ClusterCountFreeClusters(vi);
vi->FileList=NULL;
// For the slack space
if(!PGPscAddToFileList(&(vi->FileList),vi->drivestr,
WipeFreeCountCallback,vi))
{
vi->FileList=NULL;
return WFE_USERCANCEL;
}
vi->FileList=NULL;
return WFE_NOERROR;
}
// This is the callback provided to our CreateFileList call.
// It will send us every filename on the drive. We'll free
// the links in the list ourselves to cut down on memory
// consumption
BOOL WipeFreeAddFileCallback(FILELIST *fl,void *pUserValue)
{
VOLINFO *vi;
SLACKMOVE sm;
DWORD RetVal;
BOOL bDidOne;
vi=(VOLINFO *)pUserValue;
if(!fl->IsDirectory)
{
char szText[1024];
strcpy(szText,"Wiping slack space at end of files...\n");
strcat(szText,fl->name);
StatusMessage(vi,szText,FALSE);
RetVal=GetLastClusterOfFile(vi,
fl->name,
&sm);
if(vi->bCancel)
return FALSE;
// We got the tail end. Now wipe it
// If this fails, it is usually because the
// file size is zero, so no problems anyway
if((RetVal==WFE_NOERROR)&&(sm.Orig!=0))
{
int retries;
HANDLE hMoveOver;
// Now erase slack space
// Move end of file to temp space
retries=0;
hMoveOver = CreateFile( sm.name, GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
FILE_FLAG_NO_BUFFERING, 0 );
if( hMoveOver != INVALID_HANDLE_VALUE )
{
do
{
RetVal=ClusterNTWipeCluster( hMoveOver,vi,
sm.Vcn,
vi->SlackBuffer[vi->SlackMoveCount%vi->SlackBufferIndex],
sm.Size);
retries++;
vi->SlackMoveCount++;
if(vi->bCancel)
{
CloseHandle(hMoveOver);
return FALSE;
}
} while((RetVal==WFE_ALREADYCOMMIT)&&(retries<RETRIES));
CloseHandle(hMoveOver);
}
// if(RetVal!=WFE_NOERROR)
/// StatusMessage(vi,"Error", FALSE);
// else
// StatusMessage(vi,"OK", FALSE);
vi->dwClustersWritten=vi->dwClustersWritten+1;
// if(RetVal!=WFE_NOERROR)
// MessageBox(NULL,"test1","debug",MB_OK);
PutSMOnQueue(vi->OverwriteQueue,&sm);
}
if(!DoFollowBehinds(vi,&bDidOne,FALSE,FALSE))
return FALSE;
}
else
{
free(fl->name);
}
free(fl);
return (vi->bCancel);
}
DWORD CreatePGPwipepattern(VOLINFO *vi)
{
DWORD memamt,RetVal;
char *PatternBuf;
FILE *fin;
RetVal=WFE_NOERROR;
memamt=vi->sectors_per_clus*vi->sector_size;
if(vi->dwFS==FS_NTFS)
memamt=memamt*16; // NTFS works with 16 cluster segments
PatternBuf=(char *)malloc(memamt);
if(PatternBuf==0)
{
RetVal=WFE_OUTOFMEMORY;
}
else
{
// memset(PatternBuf,'o',memamt); // For testing
WritePattern(PatternBuf,vi->pattern_buffer,memamt);
fin=fopen(vi->PGPwipepattern,"wb");
if(fin==0)
{
RetVal=WFE_COULDNOTWRITE;
}
else
{
fwrite(PatternBuf,1,memamt,fin);
fclose(fin);
}
free(PatternBuf);
}
return RetVal;
}
DWORD NTDoWipe(VOLINFO *vi)
{
DWORD status,RetVal;
int delay;
RetVal=WFE_NOERROR;
vi->SlackMoveCount=vi->SlackBufferIndex=0;
vi->dwClustersWritten=vi->dwOldWritten=vi->dwClusterCount=vi->extracount=0;
// Get the NtFsControlFile entry point since undocumented
if( !(NtFsControlFile = (void *) GetProcAddress( GetModuleHandle("ntdll.dll"),
"NtFsControlFile" )) )
{
return WFE_FSNOTSUPPORTED;
}
// Open the volume
status = OpenVolume(vi);
if( status != ERROR_SUCCESS )
{
return StatusToError(status);
}
// Get a count beforehand
RetVal=CountFileClusterMoves(vi);
{
// Now obliterate all but 150 megs of free space
RetVal=BiggieWipeFreeClusters(vi);
if(RetVal==WFE_NOERROR)
{
if(vi->bNTFSInternal)
{
FreeBiggie(vi);
vi->extracount=0;
}
// Create smaller 16 cluster wipepattern
RetVal=CreatePGPwipepattern(vi);
if(RetVal==WFE_NOERROR)
{
vi->hWipe = CreateFile( vi->PGPwipepattern, GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
FILE_FLAG_NO_BUFFERING, 0 );
if( vi->hWipe == INVALID_HANDLE_VALUE )
{
// Could not open file
RetVal=WFE_COULDNOTREAD ;
}
else
{
if(vi->bNTFSInternal)
{
// Just count them for now
RetVal=ClusterWipeFreeClusters(vi,FALSE);
}
else
{
// Wipe the free clusters in this 150 meg
RetVal=ClusterWipeFreeClusters(vi,TRUE);
}
delay=2;
if(vi->dwFS==FS_NTFS)
delay=vi->SlackBufferIndex;
vi->MoveBackQueue=InitSMQueue(delay);
vi->OverwriteQueue=InitSMQueue(delay);
if(RetVal==WFE_NOERROR)
{
// Free all filled space
FreeBiggie(vi);
vi->extracount=0;
if(RetVal==WFE_NOERROR)
{
BOOL bDidOne;
// Get the files and wipe the slack
// No need to free the FileList since the callback
// does this. Tricky, but saves space and reuses complex
// code
vi->FileList=NULL;
if(!PGPscAddToFileList(&(vi->FileList),vi->drivestr,
WipeFreeAddFileCallback,vi))
RetVal=WFE_USERCANCEL;
// Cleanup
StatusMessage(vi,"Cleaning up...",FALSE);
do
{
if(!DoFollowBehinds(vi,&bDidOne,TRUE,FALSE))
{
RetVal=WFE_USERCANCEL;
break;
}
} while(bDidOne);
do
{
if(!DoFollowBehinds(vi,&bDidOne,TRUE,TRUE))
{
RetVal=WFE_USERCANCEL;
break;
}
} while(bDidOne);
}
}
CloseHandle(vi->hWipe);
}
}
DestroySMQueue(vi->MoveBackQueue);
DestroySMQueue(vi->OverwriteQueue);
}
}
FlushFileBuffers(vi->VolHandle);
CloseHandle(vi->VolHandle);
FreeBiggie(vi);
remove(vi->PGPwipepattern);
return RetVal;
}
void NTGetDriveInfo(VOLINFO *vi)
{
int rst;
DWORD NumFreeClusters;
DWORD SectorsPerCluster;
DWORD BytesPerSector;
DWORD NumClusters;
rst=GetDiskFreeSpace(vi->drivestr,
&SectorsPerCluster,
&BytesPerSector,
&NumFreeClusters,
&NumClusters);
vi->no_of_freeclusters=NumFreeClusters;
vi->no_of_clusters=NumClusters;
vi->sectors_per_clus=(USHORT)SectorsPerCluster;
vi->sector_size=(USHORT)BytesPerSector;
vi->fTotalCapacity=(FLOAT)
vi->no_of_clusters*vi->sectors_per_clus*vi->sector_size;
if(vi->dwFS==FS_FAT)
{
// Microsoft says 4086 here
// FIPs says 4079. 4079 makes more sense,
// but probably won't matter either way
if(vi->no_of_clusters <= 4079)
vi->dwFS=FS_FAT12;
else
vi->dwFS=FS_FAT16;
}
}
DWORD NTWipeFree(HWND hwnd,VOLINFO *vi,char *szRoot,
DWORD* pattern, BOOL StartWipe)
{
DWORD RetVal;
RetVal=WFE_NOERROR;
// Zero-based volume, 'A'=0, 'B'=1, 'C'=2, etc.
vi->vol0=toupper(szRoot[0])-'A';
// Create our filenames
sprintf(vi->drivestr,"%c:\\",vi->vol0+'A');
sprintf(vi->PGPwipepattern,"%c:\\",vi->vol0+'A');
strcat(vi->PGPwipepattern,"PGPwipepattern.tmp");
NTGetDriveInfo(vi);
// For clusters greater than 4K, defrag API is not supported
// because of msoft compression goof
if((vi->WinNT)&&(vi->dwFS==FS_NTFS)&&(vi->sectors_per_clus*vi->sector_size>4096))
return WFE_NTFSGREATER4K;
DisplayDiskStats(vi);
// Do wipe if so. Otherwise report stats.
if(StartWipe)
{
StatusMessage(vi,"Starting Free Space Wipe",FALSE);
RetVal=NTDoWipe(vi);
}
return RetVal;
}
/*__Editor_settings____
Local Variables:
tab-width: 4
End:
vi: ts=4 sw=4
vim: si
_____________________*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -