www.pudn.com > vdksrc.zip > VDiskExtRaw.cpp
/*
VDiskExtRaw.cpp
Raw image file class
Copyright (c) 2003 Ken Kato
*/
#include "vdkbase.h"
#include "vdkutil.h"
#ifdef USE_SPARSE_FILE
#include "SparseFile.h"
#endif
#include "VDisk.h"
#include "VDiskExtRaw.h"
#include "VDiskUtil.h"
//
// Constructor
//
VDiskExtRaw::VDiskExtRaw()
{
m_nStartOffset = 0;
m_nBackOffset = 0;
}
//
// Destructor
//
VDiskExtRaw::~VDiskExtRaw()
{
}
//
// Load and obtain parameters from extent file
//
VDKSTAT VDiskExtRaw::Load(HANDLE hFile)
{
VDKSTAT stat = VDK_OK;
m_nFileAttr = VdkGetAttribute(m_pFullPath);
if (m_nFileAttr == (ULONG)INVALID_FILE_ATTRIBUTES) {
m_nFileAttr = 0;
return VdkLastError();
}
stat = VdkGetFileSize(hFile, &m_nFileSize);
if (stat != VDK_OK) {
return stat;
}
m_nCapacity = (ULONG)(m_nFileSize >> VDK_BYTE_SHIFT_TO_SECTOR);
return VDK_OK;
}
//
// Check parameter consistency
//
VDKSTAT VDiskExtRaw::Check()
{
PVOID cbparams[3];
cbparams[0] = m_pFullPath;
//
// check file size boundary
//
if (m_nFileSize & VDK_SECTOR_ALIGNMENT_MASK) {
cbparams[1] = &m_nFileSize;
if (!VDiskCallBack(VDISK_CB_SIZE_BOUNDARY, cbparams)) {
return VDK_CANCEL;
}
SetModify();
}
//
// check file size against logical capacity
//
if ((ULONG)(m_nFileSize >> VDK_BYTE_SHIFT_TO_SECTOR) !=
m_nCapacity + m_nBackOffset) {
ULONG reply;
cbparams[1] = (PVOID)(m_nCapacity + m_nBackOffset);
cbparams[2] = (PVOID)(m_nFileSize >> VDK_BYTE_SHIFT_TO_SECTOR);
reply = VDiskCallBack(VDISK_CB_EXT_FILESIZE, cbparams);
if (reply <= m_nBackOffset) {
return VDK_CANCEL;
}
m_nCapacity = reply - m_nBackOffset;
SetModify();
}
return VDK_OK;
}
//
// Update extent file
//
VDKSTAT VDiskExtRaw::Update()
{
HANDLE hFile;
INT64 logical_size;
VDKSTAT ret;
if (!IsModified()) {
return VDK_OK;
}
//
// logical size is differenct from actual size?
//
logical_size =
(INT64)(m_nCapacity + m_nBackOffset) <<
VDK_BYTE_SHIFT_TO_SECTOR;
if (logical_size == m_nFileSize) {
ClrModify();
return VDK_OK;
}
//
// adjust actual size
//
ret = VdkOpenFile(
&hFile, m_pFullPath, strlen(m_pFullPath), FALSE);
if (ret != VDK_OK) {
return ret;
}
ret = VdkSetFileSize(hFile, logical_size);
VdkCloseFile(hFile);
if (ret == VDK_OK) {
m_nFileSize = logical_size;
}
// clear modified flag
ClrModify();
return ret;
}
//
// Create actural extent file
//
VDKSTAT VDiskExtRaw::Create(ULONG flags)
{
VDKSTAT ret;
INT64 size;
size = (INT64)(m_nCapacity + m_nBackOffset) <<
VDK_BYTE_SHIFT_TO_SECTOR;
if (!size || !m_pFullPath) {
return VDK_FUNCTION;
}
#ifdef USE_SPARSE_FILE
if (flags & VDISK_CREATE_SPARSE) {
ret = ::CreateSparse(
m_pFullPath, size, flags & VDISK_CREATE_FORCE);
}
else
#endif
{
HANDLE hFile;
//
// Create file
//
ret = VdkCreateFile(
&hFile, m_pFullPath, (flags & VDISK_CREATE_FORCE));
if (ret != VDK_OK) {
return ret;
}
ret = VdkSetFileSize(hFile, size);
VdkCloseFile(hFile);
}
if (ret == VDK_OK) {
m_nFileSize = size;
}
return ret;
}