⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scwfnt.c

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 C
📖 第 1 页 / 共 3 页
字号:
/*__________________________________________________________________________
 Copyright (C) 2002 PGP Corporation
 All rights reserved.
 
 $Id: SCwfNT.c,v 1.15 2002/11/16 08:55:23 wjb Exp $
__________________________________________________________________________*/
#include "precomp.h"

#define RETRIES 1

//
// Invalid longlong number
//
#define LLINVALID		((ULONGLONG) -1)

//
// Size of the buffer we read file mapping information into.
// The buffer is big enough to hold the 16 bytes that 
// come back at the head of the buffer (the number of entries 
// and the starting virtual cluster), as well as 512 pairs
// of [virtual cluster, logical cluster] pairs.
//
#define	FILEMAPSIZE		(512+2)

//
// Size of the bitmap buffer we pass in. Its large enough to
// hold information for the 16-byte header that's returned
// plus the indicated number of bytes, each of which has 8 bits 
// (imagine that!)
//
#define BITMAPBYTES		4096
#define BITMAPSIZE		(BITMAPBYTES+2*sizeof(ULONGLONG))

//
// Bit shifting array for efficient processing of the bitmap
//
BYTE		BitShift[] = { 1, 2, 4, 8, 16, 32, 64, 128 };

// StatusToError
//
// Takes the status messages and turns them into our
// native wipe free codes.
DWORD StatusToError( NTSTATUS Status )
{
	switch( Status ) 
	{
	case STATUS_SUCCESS:
		return WFE_NOERROR;
	case STATUS_INVALID_PARAMETER:
		return WFE_INVALPARAM; // Must be the metafile
	case STATUS_BUFFER_TOO_SMALL:
		return WFE_OUTOFMEMORY;
	case STATUS_ALREADY_COMMITTED:
	case STATUS_DELETE_PENDING:
		return WFE_ALREADYCOMMIT; // NTFS won't let us. Try anyway
	case STATUS_INVALID_DEVICE_REQUEST:
		return WFE_DRIVENOTSUPPORTED;
	case STATUS_DEVICELOCKED:
		return WFE_COULDNOTLOCK;
	case ERROR_ACCESS_DENIED:
		return WFE_ACCESSDENIED;
	default:
		/*
#if _DEBUG
		{
			char szWarn[100];

			sprintf(szWarn,"Status Error %d",Status);
			MessageBox(NULL,szWarn,"DEBUG INFO ONLY",MB_OK);
		}
#endif // _DEBUG
		*/
		return WFE_CLUSTERERROR;
	}		  
}

// OpenVolume
//
// Grabs the handle of our logical volume
DWORD OpenVolume( VOLINFO *vi ) 
{
	static char			volumeName[] = "\\\\.\\A:";

	//
	// open the volume
	//
	volumeName[4] = (char)vi->vol0 + 'A'; 
	vi->VolHandle = CreateFile( volumeName, GENERIC_READ, 
					FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 
					0, 0 );
	if( vi->VolHandle == INVALID_HANDLE_VALUE )	{

		return GetLastError();
	}

	return ERROR_SUCCESS;
}


// WipeCluster
//
// WipeCluster uses the patterns stored in filename to 
// eradicate the data in the target cluster of the logical
// drive specified.

DWORD ClusterNTWipeCluster( HANDLE sourceFile,VOLINFO *vi, ULONGLONG Vcn, ULONGLONG target,DWORD numClusters)
{
	DWORD						status;
	IO_STATUS_BLOCK				ioStatus;
	LARGE_INTEGER				startVcn, targetLcn;
	MOVEFILE_DESCRIPTOR			moveFile;

	DWORD RetVal;

	RetVal=WFE_NOERROR;

	if(numClusters>16)
	{
		int i;

		i=0;
	}

	// 
	// Get numeric parameters
	//
	startVcn.QuadPart=Vcn;
	targetLcn.QuadPart=target;

	//
	// Setup movefile descriptor and make the call
	//
	memset(&moveFile,0x00,sizeof(MOVEFILE_DESCRIPTOR));
	memset(&ioStatus,0x00,sizeof(IO_STATUS_BLOCK));

	moveFile.FileHandle = sourceFile;
	moveFile.StartVcn = startVcn;
	moveFile.TargetLcn = targetLcn;
	moveFile.NumVcns = numClusters;

	status = NtFsControlFile( vi->VolHandle, NULL, NULL, 0, &ioStatus,
						FSCTL_MOVE_FILE,
						&moveFile, sizeof( moveFile ),
						NULL, 0 );

	RetVal=StatusToError(status);

	// 
	// If the operation is pending, wait for it to finish
	//
	if( status == STATUS_PENDING ) 
	{
		WaitForSingleObject( sourceFile, INFINITE ); 

		RetVal=StatusToError(ioStatus.Status);
	}

	if(status!=STATUS_SUCCESS)
	{
		int i;

		i=0;
	}
	
//	// Handle our progress bars and look out for user cancel
//	vi->dwClustersWritten=vi->dwClustersWritten+1;
		
//	if(vi->dwFS==FS_NTFS)
		// NTFS works with 16 cluster segments
//		vi->dwClustersWritten=vi->dwClustersWritten+15; 

	return RetVal;
}

// WipeFreeClusters
//
// Given a logical drive number, routine iterates through free
// clusters and calls WipeCluster to zap the information stored
// there. Note that if changes take place on the drive while
// routine is executes, some clusters may be missed.

DWORD ClusterWipeFreeClusters( VOLINFO *vi, BOOL bWipe)
{
	DWORD						status,wipestatus;
	PBITMAP_DESCRIPTOR			bitMappings;
	ULONGLONG					startLcn;
	ULONGLONG					nextLcn;
	IO_STATUS_BLOCK				ioStatus;
	ULONGLONG					i;
	DWORD						numClusters;

	wipestatus=WFE_NOERROR;

	if(bWipe)
		StatusMessage(vi,"Wiping free space with cluster move method...", FALSE);
	else
		StatusMessage(vi,"Counting clusters for slack wipe...", FALSE);

	bitMappings=(PBITMAP_DESCRIPTOR)malloc(BITMAPSIZE*sizeof(BYTE)+1);

	//
	// Start scanning at the cluster offset the user specifies
	//
	nextLcn = 0;

	while( !(status = NtFsControlFile( vi->VolHandle, NULL, NULL, 0, &ioStatus,
						FSCTL_GET_VOLUME_BITMAP,
						&nextLcn, sizeof( ULONGLONG ),
						bitMappings, BITMAPSIZE )) ||
			 status == STATUS_BUFFER_OVERFLOW ||
			 status == STATUS_PENDING ) 
	{

		// 
		// If the operation is pending, wait for it to finish
		//
		if( status == STATUS_PENDING ) 
		{
			
			WaitForSingleObject( vi->VolHandle, INFINITE );
			
			//
			// Get the status from the status block
			//
			if( ioStatus.Status != STATUS_SUCCESS && 
				ioStatus.Status != STATUS_BUFFER_OVERFLOW ) 
			{
				free(bitMappings);

				// Error out
				return StatusToError(ioStatus.Status);
			}
		}

		//
		// Scan through the returned bitmap info, looking for empty clusters
		//
		startLcn = bitMappings->StartLcn;
	
		for( i = 0; i < min( bitMappings->ClustersToEndOfVol, 8*BITMAPBYTES); i++) 
		{
			numClusters=0;

			if(vi->bCancel)
			{
				free(bitMappings);

				return WFE_USERCANCEL;
			}

			if( !(bitMappings->Map[ i/8 ] & BitShift[ i % 8 ])) 
			{
				for(numClusters=1;
					((numClusters<16)&&((i+numClusters)<min( bitMappings->ClustersToEndOfVol, 8*BITMAPBYTES)));
					numClusters++)
				{
					if((bitMappings->Map[ (i+numClusters)/8 ] & BitShift[ (i+numClusters) % 8 ])) 
					{
						break;
					}
				}

				if(bWipe)
				{
					wipestatus=ClusterNTWipeCluster(vi->hWipe,vi, 0, startLcn + i,numClusters);
					vi->dwClustersWritten=vi->dwClustersWritten+numClusters;
				}

				if(wipestatus==WFE_NOERROR)
				{
					// Save this cluster for later slack movement operations
					if((vi->SlackBufferIndex<SLACKBUFFER)&&((vi->dwFS!=FS_NTFS)||(numClusters==16)))
					{
						vi->SlackBuffer[vi->SlackBufferIndex]=startLcn + i;
						vi->SlackBufferIndex=vi->SlackBufferIndex+1;
					}
				}

				i=i+numClusters-1;

				if(((wipestatus==WFE_ALREADYCOMMIT)||(wipestatus==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
					wipestatus=WFE_NOERROR;
				}

				if(wipestatus!=WFE_NOERROR)
				{
					free(bitMappings);
					return wipestatus;
				}
			} 

		}
	
		//
		// End of volume?
		//
		if( status != STATUS_BUFFER_OVERFLOW ) 
		{
			free(bitMappings);
			return StatusToError(STATUS_SUCCESS);
		}				

		//
		// Move to the next block
		//
		nextLcn = bitMappings->StartLcn + i;
	}

	//
	// We only get here when there's an error
	//
	free(bitMappings);

	return StatusToError(status);
}

DWORD ClusterCountFreeClusters( VOLINFO *vi)
{
	DWORD						status;
	PBITMAP_DESCRIPTOR			bitMappings;
	ULONGLONG					startLcn;
	ULONGLONG					nextLcn;
	IO_STATUS_BLOCK				ioStatus;
	ULONGLONG					i;

	StatusMessage(vi,"Counting free clusters...", FALSE);

	bitMappings=(PBITMAP_DESCRIPTOR)malloc(BITMAPSIZE*sizeof(BYTE)+1);

	if(bitMappings==NULL)
		return WFE_OUTOFMEMORY;

	//
	// Start scanning at the cluster offset the user specifies
	//
	nextLcn = 0;

	while( !(status = NtFsControlFile( vi->VolHandle, NULL, NULL, 0, &ioStatus,
						FSCTL_GET_VOLUME_BITMAP,
						&nextLcn, sizeof( ULONGLONG ),
						bitMappings, BITMAPSIZE )) ||
			 status == STATUS_BUFFER_OVERFLOW ||
			 status == STATUS_PENDING ) 
	{

		// 
		// If the operation is pending, wait for it to finish
		//
		if( status == STATUS_PENDING ) 
		{
			
			WaitForSingleObject( vi->VolHandle, INFINITE );
			
			//
			// Get the status from the status block
			//
			if( ioStatus.Status != STATUS_SUCCESS && 
				ioStatus.Status != STATUS_BUFFER_OVERFLOW ) 
			{
				free(bitMappings);

				// Error out
				return StatusToError(ioStatus.Status);
			}
		}

		//
		// Scan through the returned bitmap info, looking for empty clusters
		//
		startLcn = bitMappings->StartLcn;
	
		for( i = 0; i < min( bitMappings->ClustersToEndOfVol, 8*BITMAPBYTES); i++) 
		{
			if(vi->bCancel)
			{
				free(bitMappings);
				return WFE_USERCANCEL;
			}

			if( !(bitMappings->Map[ i/8 ] & BitShift[ i % 8 ])) 
			{
				vi->dwClusterCount++;
			} 
		}
	
		//
		// End of volume?
		//
		if( status != STATUS_BUFFER_OVERFLOW ) 
		{
			free(bitMappings);
			return StatusToError(STATUS_SUCCESS);
		}				

		//
		// Move to the next block
		//
		nextLcn = bitMappings->StartLcn + i;
	}

	//
	// We only get here when there's an error
	//
	free(bitMappings);

	return StatusToError(status);
}

// GetLastClusterOfFile
//
// Loops through till it finds the last cluster in the chain

DWORD GetLastClusterOfFile(VOLINFO *vi, char *fileName, SLACKMOVE *sm)
{
	DWORD						status;
	int							i;
	HANDLE						sourceFile;
	IO_STATUS_BLOCK				ioStatus;
	ULONGLONG					startVcn;
	PGET_RETRIEVAL_DESCRIPTOR	fileMappings;
	int							lines = 0;

	// Save name of file for later
	sm->name=fileName;
	sm->Orig=sm->Vcn=sm->Size=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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -