I'm facing issue On my disk cloning. (ie.) OS partition is coming as RAW instead of NTFS file system after cloning completed.
I have used FSCTL_GET_VOLUME_BITMAP Device IO Control API for getting volume bitmap buffer. Using this volume bitmap i have cloned only used clusters from source disk and written in the same offset of destination disk. In the free cluster positions left as it is.
Only used clusters cloning will cause any issue?
Is it correct for both resident & non-resident content in the volume bitmap?. because i didn't considered non-resident attributes. Simply i cloned only used clusters using the following code.
I am facing this issue only with Windows server computers.
Please any one suggest the way to solve my issue. find the code snippet below.
Finding used clusters
BOOL IsClusterUsed (UINT64 Cluster)
{
return ((BitmapBuffer[Cluster / 32] & (1 << (Cluster % 32))) ? TRUE : FALSE);
}
Getting volume Bitmap:
STARTING_LCN_INPUT_BUFFER StartingLCN;
VOLUME_BITMAP_BUFFER *Bitmap = NULL;
ULONGLONG BitmapSize;
DWORD BytesReturned1;
BOOL Status;
ULONGLONG ClusterCount = 0;
DWORD BytesReturned = 0;
_tprintf(L"[%s %d]>>GetBitmap()volume Vol(%s)\n",
gpCFileName,
__LINE__,
i_VolumeName);
if(ISNULL(o_BitmapBuffer) || ISNULL(o_Size))
{
_tprintf(L"[%s %d]>>GetBitmap()Input null open volume Vol(%s)\n",
gpCFileName,
__LINE__,
i_VolumeName);
return -1;
}
HANDLE hFile=CreateFile(L"\\\\.\\C:",GENERIC_READ,FILE_SHARE_READ | FILE_SHARE_WRITE,0,OPEN_EXISTING,0,0);
if(hFile == INVALID_HANDLE_VALUE) // this may happen if another program is already reading from disk
{
LastError = ::GetLastError();
INFOLOG(L"[%s %d]>>GetBitmap()-Unable to open volume Vol(%s) LError(0x%x)\n",
gpCFileName,
__LINE__,
i_VolumeName,
LastError);
CloseHandle(hFile);
return -1;
}
StartingLCN.StartingLcn.QuadPart = 0;
BitmapSize = sizeof (VOLUME_BITMAP_BUFFER) + 4;
Bitmap = (VOLUME_BITMAP_BUFFER *) malloc ((size_t)BitmapSize);
LastError = ::GetLastError();
if(ISNULL(Bitmap))
{
_tprintf(L"[%s %d]>>GetBitmap()-Couldn't properly read volume Bitmap Vol(%s) size(%d) LError(0x%x)\n",
gpCFileName,
__LINE__,
i_VolumeName,
(size_t)BitmapSize,
LastError);
return -1;
}
Status = DeviceIoControl( hFile, FSCTL_GET_VOLUME_BITMAP, &StartingLCN, sizeof (StartingLCN), Bitmap, (DWORD)BitmapSize, &BytesReturned1, NULL);
LastError = ::GetLastError();
if (Status == FALSE && LastError != ERROR_MORE_DATA)
{
SECURE_FREE(Bitmap);
_tprintf(L"[%s %d]>>GetBitmap()-Unable to get Bitmap Vol(%s) LError(0x%x)\n",
gpCFileName,
__LINE__,
i_VolumeName,
LastError);
return -1;
}
ClusterCount = Bitmap->BitmapSize.QuadPart - Bitmap->StartingLcn.QuadPart;//TOT noof clusters
//cout<<"\n Tot no of clusters :"<<ClusterCount<<"\n";
//cout<<"\n StartingLcn :"<<Bitmap->StartingLcn.QuadPart<<"\n";
//printf("Reallocate Memory \n");
BitmapSize = sizeof (VOLUME_BITMAP_BUFFER) + ((Bitmap->BitmapSize.QuadPart) / i_SectorPerCluster) + 1;
Bitmap = (VOLUME_BITMAP_BUFFER *) realloc (Bitmap, (size_t)BitmapSize);
//cout<<"\n Realloc BitmapSize :"<<BitmapSize<<"\n";
//cout<<"\n Realloc size_t BitmapSize :"<<(size_t)BitmapSize<<"\n";
//cout<<"\n GetClusterSize :"<<this->GetClusterSize()<<"\n";
Status = DeviceIoControl( hFile, FSCTL_GET_VOLUME_BITMAP, &StartingLCN, sizeof (StartingLCN), Bitmap, (DWORD)BitmapSize, &BytesReturned, NULL);
LastError = ::GetLastError();
if (Status == FALSE)
{
_tprintf(L"[%s %d]>>GetBitmap()-Couldn't properly read volume Bitmap Vol(%s) Bytes(%ld) LError(0x%x)\n",
gpCFileName,
__LINE__,
i_VolumeName,
BytesReturned,
LastError);
SECURE_FREE(Bitmap);
return -1;
}
ULONGLONG len = sizeof(UINT32) * (1 + (ClusterCount / 32));
*o_BitmapBuffer = (PUINT)new BYTE[(size_t)len];
memcpy (*o_BitmapBuffer, Bitmap->Buffer, ((size_t)(len)));
*o_Size = (DWORD)len;
SECURE_FREE(Bitmap);
CloseHandle(hFile);