|
|
#include "imagpart.h"
BOOL BuildClusterBitmap( IN FilesystemType FsType, IN HPARTITION PartitionHandle, IN UINT FileHandle, IN OUT PARTITION_IMAGE *PartitionImage )
/*++
Routine Description:
This routine builds a bitmap representing all clusters in the source volume, 1 bit per cluster (0=unused, 1=used). The bitmap is written into a file.
Arguments:
FsType - supplies the type of the file system
PartitionHandle - supplies handle to source partition
FileHandle - supplies handle for output file. It is assumed that this file is empty. On output this file is rewound to offset 0.
PartitionImage - supplies information about the source partition. On output, the following fields are filled in:
LastUsedCluster UsedClusterCount
Return Value:
Boolean value indicating outcome. If false, a message will have been printed out explaining why.
--*/
{ BOOL b;
if(FsType == FilesystemFat) { b = FatBuildClusterBitmap(PartitionHandle,FileHandle,PartitionImage); } else { if(FsType == FilesystemNtfs) { b = NtfsBuildClusterBitmap(PartitionHandle,FileHandle,PartitionImage); } else { fprintf(stderr,"\n%s\n",textUnsupportedFs); b = FALSE; } }
if(b) { DosSeek(FileHandle,0,DOSSEEK_START); }
return(b); }
FPBYTE _ClusterBuffer; ULONG _BaseCluster; UINT _ClusterFileHandle; ULONG _LastUsedCluster; ULONG _NextClusterToExamine; BYTE BitValue[8] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
VOID InitClusterBuffer( IN FPBYTE _512ByteBuffer, IN UINT FileHandle ) { _ClusterBuffer = _512ByteBuffer; _BaseCluster = 0L; _ClusterFileHandle = FileHandle;
memset(_512ByteBuffer,0,512); }
BOOL MarkClusterUsed( IN ULONG Cluster ) { unsigned Written; BOOL NeedToZero;
//
// See if the cluster we're updating is past the end of what
// we're currently buffering. Note that it could be way beyond.
//
NeedToZero = TRUE; while(Cluster >= _BaseCluster+(8*512)) {
if(_dos_write(_ClusterFileHandle,_ClusterBuffer,512,&Written) || (Written != 512)) { fprintf(stderr,"\n%s\n",textFileWriteError); return(FALSE); }
_BaseCluster += 8*512;
if(NeedToZero) { memset(_ClusterBuffer,0,512); NeedToZero = FALSE; } }
//
// Set the relevent bit.
//
Cluster -= _BaseCluster; _ClusterBuffer[Cluster/8] |= BitValue[Cluster%8];
return(TRUE); }
BOOL FlushClusterBuffer( VOID ) { unsigned Written; unsigned u; BOOL b;
u = _dos_write(_ClusterFileHandle,_ClusterBuffer,512,&Written);
b = (!u && (Written == 512));
if(!b) { fprintf(stderr,"\n%s\n",textFileWriteError); } return(b); }
BOOL InitClusterMap( OUT FPBYTE _512ByteBuffer, IN UINT FileHandle, IN ULONG LastUsedCluster ) { unsigned Read;
_ClusterBuffer = _512ByteBuffer; _ClusterFileHandle = FileHandle; _BaseCluster = 0L; _NextClusterToExamine = 0L; _LastUsedCluster = LastUsedCluster;
if(_dos_read(FileHandle,_ClusterBuffer,512,&Read) || (Read != 512)) { fprintf(stderr,"\n%s\n",textFileReadFailed); return(FALSE); }
return(TRUE); }
BOOL GetNextClusterRun( OUT ULONG *StartCluster, OUT ULONG *ClusterCount ) { UINT cluster; unsigned Read; BOOL b;
*ClusterCount=0;
//
// Scan forward for the next 1 bit
//
while(_NextClusterToExamine <= _LastUsedCluster) {
//
// Reload the cluster buffer if necessary.
//
if(_NextClusterToExamine && !(_NextClusterToExamine % (512*8))) { if(_dos_read(_ClusterFileHandle,_ClusterBuffer,512,&Read) || (Read != 512)) { fprintf(stderr,"\n%s\n",textFileReadFailed); return(FALSE); } _BaseCluster += 512*8; }
cluster = (UINT)(_NextClusterToExamine - _BaseCluster);
//
// To simplify things, the run will not span into the next sector
// of the cluster map.
//
b = FALSE;
while((_ClusterBuffer[cluster/8] & BitValue[cluster%8]) && (cluster < (512*8)) && (_NextClusterToExamine <= _LastUsedCluster)) {
if(!b) { *StartCluster = _NextClusterToExamine; b = TRUE; } *ClusterCount += 1; cluster++; _NextClusterToExamine++; }
if(b) { return(TRUE); }
_NextClusterToExamine++; }
//
// No more used clusters.
//
return(TRUE); }
|