📄 scwfnt.c
字号:
for( i = 0; i < (ULONGLONG) fileMappings->NumberOfPairs; i++ )
{
//
// On NT 4.0, a compressed virtual run (0-filled) is
// identified with a cluster offset of -1
//
if( fileMappings->Pair[i].Lcn == LLINVALID )
{
// Ignore virtual runs since OS is supposed to fill slack
// with zeros
}
else
{
// This gives us the last cluster Vcn (First+Length-1)
sm->Vcn=startVcn+(fileMappings->Pair[i].Vcn - startVcn )-1;
if(vi->dwFS==FS_NTFS)
{
// We need to 16 cluster align it if NTFS
sm->Vcn=(sm->Vcn/16)*16;
}
// Should always be < 16
sm->Size=(ULONG)(fileMappings->Pair[i].Vcn - (sm->Vcn) );
if(sm->Size>16)
{
sm->Size=16;
// Really screwed up
}
// This gives us the last cluster Lcn (Start Location + offset)
sm->Orig=fileMappings->Pair[i].Lcn+(sm->Vcn-startVcn);
if(sm->Orig<fileMappings->Pair[i].Lcn)
{
int i;
i=0;
}
}
startVcn = fileMappings->Pair[i].Vcn;
}
//
// If the buffer wasn't overflowed, then we're done
//
if( !status ) break;
}
CloseHandle( sourceFile );
free(fileMappings);
return StatusToError(status);
}
PGPError PGPscClusterFileGather(char *fileName,PCWF *cwflist)
{
DWORD status;
int i;
HANDLE sourceFile;
IO_STATUS_BLOCK ioStatus;
ULONGLONG startVcn;
PGET_RETRIEVAL_DESCRIPTOR fileMappings;
int lines = 0;
PGPError err;
static char volumeName[] = "\\\\.\\A:";
HANDLE hVolume;
// Get the NtFsControlFile entry point since undocumented
if( !(NtFsControlFile = (void *) GetProcAddress( GetModuleHandle("ntdll.dll"),
"NtFsControlFile" )) )
{
return kPGPError_UnknownError;
}
//
// open the volume
//
volumeName[4] = (char)'D';
hVolume = CreateFile( volumeName, GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
0, 0 );
if( hVolume == INVALID_HANDLE_VALUE )
{
return kPGPError_UnknownError;
}
err=kPGPError_NoErr;
//
// Open the file
//
sourceFile = CreateFile( fileName, GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
FILE_FLAG_NO_BUFFERING, 0 );
if( sourceFile == INVALID_HANDLE_VALUE )
{
err=kPGPError_CantOpenFile;
}
else
{
//
// Start dumping the mapping information. Go until we hit the end of the
// file.
//
startVcn = 0;
fileMappings = (PGET_RETRIEVAL_DESCRIPTOR)
malloc(FILEMAPSIZE*sizeof(ULONGLONG));
if(fileMappings==NULL)
{
err=kPGPError_OutOfMemory;
}
else
{
while( !(status = NtFsControlFile( sourceFile, NULL, NULL, 0, &ioStatus,
FSCTL_GET_RETRIEVAL_POINTERS,
&startVcn, sizeof( startVcn ),
fileMappings, FILEMAPSIZE * sizeof(LARGE_INTEGER) ) ) ||
status == STATUS_BUFFER_OVERFLOW ||
status == STATUS_PENDING )
{
//
// If the operation is pending, wait for it to finish
//
if( status == STATUS_PENDING )
{
WaitForSingleObject( sourceFile, INFINITE );
//
// Get the status from the status block
//
if( ioStatus.Status != STATUS_SUCCESS &&
ioStatus.Status != STATUS_BUFFER_OVERFLOW )
{
free(fileMappings);
// Error out
err=kPGPError_FileOpFailed;
//dwError=StatusToError(ioStatus.Status);
break;
}
}
//
// Loop through the buffer of number/cluster pairs, printing them
// out.
//
startVcn = fileMappings->StartVcn;
for( i = 0; i < (ULONGLONG) fileMappings->NumberOfPairs; i++ )
{
//
// On NT 4.0, a compressed virtual run (0-filled) is
// identified with a cluster offset of -1
//
if( fileMappings->Pair[i].Lcn == LLINVALID )
{
// Ignore virtual runs since OS is supposed to fill slack
// with zeros
}
else
{
PCWF cwf;
cwf=(PCWF)malloc(sizeof(CWF));
if(cwf==NULL)
{
err=kPGPError_NoErr;
break;
}
else
{
memset(cwf,0x00,sizeof(CWF));
// This gives us the last cluster Vcn (First+Length-1)
cwf->Lcn=fileMappings->Pair[i].Lcn;
cwf->Size=(ULONG)(fileMappings->Pair[i].Vcn - startVcn);
cwf->next=(*cwflist);
*cwflist=cwf;
}
}
startVcn = fileMappings->Pair[i].Vcn;
}
//
// If the buffer wasn't overflowed, then we're done
//
if( !status ) break;
}
free(fileMappings);
}
CloseHandle( sourceFile );
}
CloseHandle(hVolume);
return err;
}
PGPError PGPscClusterFileWipe(char *fileName,PCWF cwflist)
{
int lines = 0;
PGPError err;
char szPGPwipepattern[MAX_PATH];
static char volumeName[] = "\\\\.\\A:";
HANDLE hVolume;
// Get the NtFsControlFile entry point since undocumented
if( !(NtFsControlFile = (void *) GetProcAddress( GetModuleHandle("ntdll.dll"),
"NtFsControlFile" )) )
{
return kPGPError_UnknownError;
}
//
// open the volume
//
volumeName[4] = (char)'D';
hVolume = CreateFile( volumeName, GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
0, 0 );
if( hVolume == INVALID_HANDLE_VALUE )
{
return kPGPError_UnknownError;
}
strcpy(szPGPwipepattern,"d:\\PGPwipepattern.tmp");
err=kPGPError_NoErr;
if(IsntPGPError(err))
{
int memamt;
char *pPat;
FILE *fin;
DeleteFile(fileName);
memamt=4096;
pPat=(char *)malloc(memamt);
if(pPat==NULL)
{
err=kPGPError_NoErr;
}
else
{
memset(pPat,0x11,memamt);
fin=fopen(szPGPwipepattern,"wb");
if(fin==0)
{
err=kPGPError_WriteFailed;
}
else
{
PCWF freeatlast;
HANDLE hFile;
fwrite(pPat,1,memamt,fin);
fclose(fin);
free(pPat);
hFile = CreateFile( szPGPwipepattern, GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
FILE_FLAG_NO_BUFFERING, 0 );
while(cwflist!=NULL)
{
DWORD status;
IO_STATUS_BLOCK ioStatus;
MOVEFILE_DESCRIPTOR moveFile;
ULONG i;
//
// Setup movefile descriptor and make the call
//
memset(&moveFile,0x00,sizeof(MOVEFILE_DESCRIPTOR));
memset(&ioStatus,0x00,sizeof(IO_STATUS_BLOCK));
moveFile.FileHandle = hFile;
moveFile.StartVcn.QuadPart = 0;
for(i=0;i<cwflist->Size;i=i+16)
{
moveFile.TargetLcn.QuadPart = cwflist->Lcn+i;
moveFile.NumVcns = cwflist->Size-i;
if(moveFile.NumVcns>16)
moveFile.NumVcns=16;
status = NtFsControlFile( hVolume, NULL, NULL, 0, &ioStatus,
FSCTL_MOVE_FILE,
&moveFile, sizeof( moveFile ),
NULL, 0 );
//
// If the operation is pending, wait for it to finish
//
if( status == STATUS_PENDING )
{
WaitForSingleObject( hFile, INFINITE );
}
StatusToError(status);
}
freeatlast=cwflist;
cwflist=cwflist->next;
free(freeatlast);
}
DeleteFile(szPGPwipepattern);
}
}
}
CloseHandle(hVolume);
return (DWORD)err;
}
// GetLastClusterOfFile
//
// Loops through till it finds the last cluster in the chain
DWORD GetSlackClustersInFile(VOLINFO *vi, char *fileName)
{
DWORD status;
int i;
HANDLE sourceFile;
IO_STATUS_BLOCK ioStatus;
ULONGLONG startVcn;
PGET_RETRIEVAL_DESCRIPTOR fileMappings;
int lines = 0;
//
// Open the file
//
sourceFile = CreateFile( fileName, GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
FILE_FLAG_NO_BUFFERING, 0 );
if( sourceFile == INVALID_HANDLE_VALUE )
return WFE_COULDNOTREAD;
//
// Start dumping the mapping information. Go until we hit the end of the
// file.
//
startVcn = 0;
fileMappings = (PGET_RETRIEVAL_DESCRIPTOR)
malloc(FILEMAPSIZE*sizeof(ULONGLONG));
while( !(status = NtFsControlFile( sourceFile, NULL, NULL, 0, &ioStatus,
FSCTL_GET_RETRIEVAL_POINTERS,
&startVcn, sizeof( startVcn ),
fileMappings, FILEMAPSIZE * sizeof(LARGE_INTEGER) ) ) ||
status == STATUS_BUFFER_OVERFLOW ||
status == STATUS_PENDING )
{
//
// If the operation is pending, wait for it to finish
//
if( status == STATUS_PENDING ) {
WaitForSingleObject( sourceFile, INFINITE );
//
// Get the status from the status block
//
if( ioStatus.Status != STATUS_SUCCESS &&
ioStatus.Status != STATUS_BUFFER_OVERFLOW )
{
free(fileMappings);
// Error out
return StatusToError(ioStatus.Status);
}
}
//
// Loop through the buffer of number/cluster pairs, printing them
// out.
//
startVcn = fileMappings->StartVcn;
for( i = 0; i < (ULONGLONG) fileMappings->NumberOfPairs; i++ )
{
if(vi->bCancel)
{
free(fileMappings);
CloseHandle( sourceFile );
return WFE_USERCANCEL;
}
//
// On NT 4.0, a compressed virtual run (0-filled) is
// identified with a cluster offset of -1
//
if( fileMappings->Pair[i].Lcn == LLINVALID )
{
// Ignore virtual runs since OS is supposed to fill slack
// with zeros
}
else
{
ULONGLONG freecluster,chainindex,chunk;
chunk=0;
if(vi->dwFS==FS_NTFS)
{
chunk=15;
}
for(chainindex=startVcn;
chainindex<startVcn+(fileMappings->Pair[i].Vcn - startVcn );
chainindex=chainindex+1+chunk)
{
if(chainindex+chunk<
startVcn+(fileMappings->Pair[i].Vcn - startVcn ))
{
// Hey it's a good length chunk!
freecluster=fileMappings->Pair[i].Lcn+
(chainindex-startVcn);
// Save this cluster for later slack movement operations
if(vi->SlackBufferIndex<SLACKBUFFER)
{
vi->SlackBuffer[vi->SlackBufferIndex]=freecluster;
vi->SlackBufferIndex=vi->SlackBufferIndex+1;
}
else
{
// We're done
free(fileMappings);
CloseHandle( sourceFile );
return StatusToError(STATUS_SUCCESS);
}
}
}
}
startVcn = fileMappings->Pair[i].Vcn;
}
//
// If the buffer wasn't overflowed, then we're done
//
if( !status ) break;
}
CloseHandle( sourceFile );
free(fileMappings);
return StatusToError(status);
}
DWORD DoFollowBehinds(VOLINFO *vi,BOOL *pbDidOne,BOOL bCleanOver,BOOL bCleanBack)
{
SLACKMOVE sm;
DWORD RetVal;
*pbDidOne=FALSE;
// These steps are followed 100 clusters behind
// in order to assure NTFS has had time to deallocate
// the space
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -