📄 wfnt.c
字号:
CloseHandle( sourceFile );
return StatusToError(status);
}
DWORD GetOrigForFileList(VOLINFO *vi)
{
DWORD count;
FILELIST *index;
DWORD RetVal;
index=vi->FileList;
count=0;
RetVal=WFE_NOERROR;
while(index!=NULL)
{
if(!index->IsDirectory)
{
RetVal=GetLastClusterOfFile(vi,
index->name,
&(vi->SlackMove[count]));
// Probably somebody has a lock on the file. ignore
//if(RetVal!=WFE_NOERROR)
// return RetVal;
count++;
}
index=index->next;
}
if(((RetVal==WFE_ALREADYCOMMIT)||(RetVal==WFE_INVALPARAM))&&(vi->dwFS==FS_NTFS))
{
// Couldn't do the move because of MFT, or user is mucking
// around.... just skip it and we'll get it on the next pass.
// Only applies to NTFS
RetVal=WFE_NOERROR;
}
return RetVal;
}
DWORD CountFileList(FILELIST *index)
{
DWORD count;
count=0;
while(index!=NULL)
{
if(!index->IsDirectory)
count++;
index=index->next;
}
return count;
}
DWORD AbortSlackMovements(VOLINFO *vi,DWORD RetVal,BOOL bSafe)
{
DWORD rst;
if(RetVal==WFE_USERCANCEL)
{
// Turn off the cancel button cancel
bGlobalCancel=FALSE;
// We're just counting, not moving. Go ahead and abort.
if(vi->bCountClusters)
return WFE_USERCANCEL;
if(!bSafe)
{
rst=PGPscMessageBox (vi->hwnd,IDS_PGPWARNING,IDS_ABORTWILLFRAG,
MB_YESNO|MB_DEFBUTTON2|MB_ICONEXCLAMATION);
if(rst==IDNO)
return WFE_NOERROR;
}
// It's safe to abort here.
return WFE_USERCANCEL;
}
// Couldn't do the move because of MFT, or user is mucking
// around.... just skip it and we'll get it on the next pass.
// Only applies to NTFS
if(((RetVal==WFE_ALREADYCOMMIT)||(RetVal==WFE_INVALPARAM))&&(vi->dwFS==FS_NTFS))
return WFE_NOERROR;
return RetVal;
}
DWORD DoSlackMovements(VOLINFO *vi)
{
char fileName[MAX_PATH];
DWORD i;
DWORD RetVal;
DWORD BufferLoop;
DWORD Start,End,ModAmt;
BOOL bAbortASAP;
bAbortASAP=FALSE;
RetVal=WFE_NOERROR;
sprintf(fileName, "%C:\\%s", vi->vol0+'A', "PGPwipepattern.tmp" );
ModAmt=SLACKBUFFER;
if(vi->SlackBufferIndex<SLACKBUFFER)
ModAmt=vi->SlackBufferIndex;
if(ModAmt==0)
return WFE_COULDNOTWRITE;
// Move Pattern out of the way
// in case its in the last temp
RetVal=NTWipeCluster( vi,
fileName,
0,
vi->PatternBuffer);
if(RetVal==WFE_USERCANCEL)
bAbortASAP=TRUE;
RetVal=AbortSlackMovements(vi,RetVal,TRUE);
if(RetVal!=WFE_NOERROR)
return RetVal;
// Reuse our temp buffer in ModAmt increments
for(BufferLoop=0;BufferLoop<(vi->SlackMoveCount+ModAmt-1)/ModAmt;BufferLoop++)
{
Start=ModAmt*BufferLoop;
End=Start+ModAmt;
if(vi->SlackMoveCount<End)
End=vi->SlackMoveCount;
// Move end of files to temp
for(i=Start;i<End;i++)
{
// Don't do bogus files
if(vi->SlackMove[i].Orig==0)
{
}
else
{
RetVal=NTWipeCluster( vi,
vi->SlackMove[i].name,
vi->SlackMove[i].Vcn,
vi->SlackBuffer[i%ModAmt]);
if(RetVal==WFE_USERCANCEL)
bAbortASAP=TRUE;
RetVal=AbortSlackMovements(vi,RetVal,FALSE);
if(RetVal!=WFE_NOERROR)
return RetVal;
}
}
// Wipe former location
for(i=Start;i<End;i++)
{
// Don't do bogus files
if(vi->SlackMove[i].Orig==0)
{
}
else
{
RetVal=NTWipeCluster( vi,
fileName,
0,
vi->SlackMove[i].Orig);
if(RetVal==WFE_USERCANCEL)
bAbortASAP=TRUE;
RetVal=AbortSlackMovements(vi,RetVal,FALSE);
if(RetVal!=WFE_NOERROR)
return RetVal;
}
}
// Move Pattern out of the way
// since its in the last orig
RetVal=NTWipeCluster( vi,
fileName,
0,
vi->PatternBuffer);
if(RetVal==WFE_USERCANCEL)
bAbortASAP=TRUE;
RetVal=AbortSlackMovements(vi,RetVal,FALSE);
if(RetVal!=WFE_NOERROR)
return RetVal;
// Move back. Not necessary, but prevents fragmentation
for(i=Start;i<End;i++)
{
// Don't do bogus files
if(vi->SlackMove[i].Orig==0)
{
}
else
{
RetVal=NTWipeCluster( vi,
vi->SlackMove[i].name,
vi->SlackMove[i].Vcn,
vi->SlackMove[i].Orig);
if(RetVal==WFE_USERCANCEL)
bAbortASAP=TRUE;
RetVal=AbortSlackMovements(vi,RetVal,FALSE);
if(RetVal!=WFE_NOERROR)
return RetVal;
}
}
// We've completed a pass with fragmentation issues figured
// out. Its safe to abort.
if(bAbortASAP)
return WFE_USERCANCEL;
}
// Not necessary, but wipe temp spots too
for(i=0;i<ModAmt;i++)
{
RetVal=NTWipeCluster( vi,
fileName,
0,
vi->SlackBuffer[i]);
if(RetVal==WFE_USERCANCEL)
bAbortASAP=TRUE;
RetVal=AbortSlackMovements(vi,RetVal,TRUE); // safe to get out here
if(RetVal!=WFE_NOERROR)
return RetVal;
}
return WFE_NOERROR;
}
DWORD NTDoWipe(VOLINFO *vi)
{
DWORD status,RetVal;
char drivestr[50];
DWORD memamt;
char StrRes[500];
RetVal=WFE_NOERROR;
LoadString (g_hinst, IDS_SCANNINGDISK, StrRes, sizeof(StrRes));
StatusMessage(StrRes, FALSE);
sprintf(drivestr,"%c:\\",vi->vol0+'A');
// Get the NtFsControlFile entry point since undocumented
if( !(NtFsControlFile = (void *) GetProcAddress( GetModuleHandle("ntdll.dll"),
"NtFsControlFile" )) )
{
return WFE_FSNOTSUPPORTED;
}
vi->FileList=NULL;
// Enumerate the files on the drive
RetVal=AddToFileList(&(vi->FileList),drivestr,&bGlobalCancel);
if(!RetVal)
{
FreeFileList(vi->FileList);
return WFE_USERCANCEL;
}
// Find the number of files
vi->SlackMoveCount=CountFileList(vi->FileList);
// Allocate a slack movement array
memamt=vi->SlackMoveCount*sizeof(SLACKMOVE);
vi->SlackMove=(SLACKMOVE *)malloc(memamt);
memset(vi->SlackMove,0x00,memamt);
// Open the volume
status = OpenVolume(vi);
if( status != ERROR_SUCCESS )
{
return StatusToError(status);
}
// Get the last cluster for each file (Orig)
RetVal=GetOrigForFileList(vi);
if(RetVal==WFE_NOERROR)
{
// Now, wipe the free clusters, grabbing Temp along the way
RetVal=NTWipeFreeClusters(vi);
if(RetVal==WFE_NOERROR)
{
// With this information, wipe the slack space
RetVal=DoSlackMovements(vi);
}
}
// Done with File List... Free it
FreeFileList(vi->FileList);
// Done with slack space info.. Free it
if(vi->SlackMove)
free(vi->SlackMove);
CloseHandle(vi->VolHandle);
return RetVal;
}
void NTGetDriveInfo(VOLINFO *vi)
{
int rst;
DWORD NumFreeClusters;
DWORD SectorsPerCluster;
DWORD BytesPerSector;
DWORD NumClusters;
char drivestr[50];
sprintf(drivestr,"%c:\\",vi->vol0+'A');
rst=GetDiskFreeSpace(drivestr,
&SectorsPerCluster,
&BytesPerSector,
&NumFreeClusters,
&NumClusters);
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;
char filename[MAX_PATH];
char *PatternBuf;
int memamt;
FILE *fin;
// 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;
// Zero-based volume, 'A'=0, 'B'=1, 'C'=2, etc.
vi->vol0=toupper(szRoot[0])-'A';
NTGetDriveInfo(vi);
DisplayDiskStats(vi);
// Do wipe if so. Otherwise report stats.
if(StartWipe)
{
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);
// Create our pattern file
sprintf(filename,"%c:\\",vi->vol0+'A');
strcat(filename,"PGPwipepattern.tmp");
fin=fopen(filename,"wb");
if(fin==0)
{
RetVal=WFE_COULDNOTWRITE;
}
else
{
fwrite(PatternBuf,1,memamt,fin);
fclose(fin);
free(PatternBuf);
vi->bCountClusters=TRUE;
RetVal=NTDoWipe(vi);
if(RetVal==WFE_NOERROR)
{
vi->bCountClusters=FALSE;
RetVal=NTDoWipe(vi);
}
_unlink (filename);
}
}
}
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 + -