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

📄 vdiskcowd.cpp

📁 Virtual Disk Driver
💻 CPP
字号:
/*	VDiskCowd.cpp	COWDisk class	Copyright (c) 2003 Ken Kato*/#include "vdkbase.h"#include "vdkutil.h"#include "cowdisk.h"#include "VDiskCowd.h"#include "VDiskExtCowd.h"#include "VDiskUtil.h"////	Constructor -- set default members//VDiskCowd::VDiskCowd(){	m_nVMwareVer	= 3;	m_nHardwareVer	= COWD_HARDWARE_VMWARE3;}////	Destructor//VDiskCowd::~VDiskCowd(){}////	Initialize instance from a VMware 2.x/3.x virtual file//VDKSTAT VDiskCowd::Initialize(PCHAR pPath){	CHAR	path[MAX_PATH];	ULONG	total_extents;	ULONG	idx;	VDKSTAT	ret;	HANDLE	hFile;	ULONG	result;	COWD_HEADER	cowd;	//	check parameter	if (!pPath || !*pPath) {		return VDK_PARAM;	}	//	store path	if ((ret = StorePath(pPath)) != VDK_OK) {		return ret;	}	//	open file	ret = VdkOpenFile(&hFile, pPath, strlen(pPath), TRUE);	if (ret != VDK_OK) {		return ret;	}	//	read COWD header	ret = VdkReadFileAt(hFile, 0, &cowd, sizeof(cowd), &result);	VdkCloseFile(hFile);	if (ret != VDK_OK) {		return ret;	}	if (result != sizeof(cowd)) {		return VDK_EOF;	}	//	process header information	if (cowd.sec0.Version == COWD_FILEVER_VMWARE2) {		m_nVMwareVer = 2;	}	else {		m_nVMwareVer = 3;	}	//	//	decide how many extents should be present	//	if (COWD_IS_MULTI(cowd.sec0.Flags)) {		total_extents = cowd.sec3.FilesPerDisk;		if (cowd.sec3.FileOrdinal) {			//			// adjust base file name --			// if the source path has a sequence number, remove it			//			idx = strlen(m_pBody);			if (idx > 3 && *(m_pBody + idx - 3) == '-' &&				(ULONG)atol(m_pBody + idx - 2) == cowd.sec3.FileOrdinal + 1) {				*(m_pBody + idx - 3) = '\0';			}		}	}	else {		total_extents = 1;	}	//	// initialize each extent object	//	for (idx = 0; idx < total_extents; idx++) {		VDiskExtCowd *ext;		ext = new VDiskExtCowd;		if (!ext) {			return VdkLastError();		}		ret = AddExtent(ext);		if (ret != VDK_OK) {			delete ext;			return ret;		}		GetExtentPath(path, idx);		ret = VDiskSearchFile(&hFile, path, NULL);		if (ret != VDK_OK) {			return ret;		}		ret = ext->SetPath(path);		if (ret == VDK_OK) {			ret = ext->Load(hFile);		}		VdkCloseFile(hFile);		if (ret != VDK_OK) {			return ret;		}	}	return Check();}////	check COWDisk consistency//VDKSTAT VDiskCowd::Check(){	ULONG total_sectors;	PCOWD_SECTOR_0 sec0_0;	PCOWD_SECTOR_2 sec2_0;	PCOWD_SECTOR_3 sec3_0;	PVOID cbparams[4];	ULONG idx;	VDKSTAT ret;	for (idx = 0; idx < m_nExtents; idx++) {		VDiskExtCowd *ext = (VDiskExtCowd *)m_ppExtents[idx];		ret = ext->Check();		if (ret != VDK_OK) {			return ret;		}		if (ext->IsModified()) {			SetFlag(VDISK_FLAG_DIRTY);		}		if (ext->GetSec3()->FileOrdinal != idx) {			cbparams[0] = ext->GetFileName();			cbparams[1] = (PVOID)ext->GetSec3()->FileOrdinal;			cbparams[2] = (PVOID)idx;			if (!VDiskCallBack(VDISK_CB_COWD_ORDINAL, cbparams)) {				return VDK_CANCEL;			}			ext->GetSec3()->FileOrdinal = idx;			ext->SetModify();			SetFlag(VDISK_FLAG_DIRTY);		}	}	//	//	check extent parameters consistency	//	sec0_0 = ((VDiskExtCowd *)m_ppExtents[0])->GetSec0();	sec2_0 = ((VDiskExtCowd *)m_ppExtents[0])->GetSec2();	sec3_0 = ((VDiskExtCowd *)m_ppExtents[0])->GetSec3();	cbparams[0] = m_ppExtents[0]->GetFullPath();	for (idx = 1; idx < m_nExtents; idx++) {		BOOL conflict = FALSE, fatal = FALSE;		PCOWD_SECTOR_0 sec0 = ((VDiskExtCowd *)m_ppExtents[idx])->GetSec0();		PCOWD_SECTOR_2 sec2 = ((VDiskExtCowd *)m_ppExtents[idx])->GetSec2();		PCOWD_SECTOR_3 sec3 = ((VDiskExtCowd *)m_ppExtents[idx])->GetSec3();		cbparams[2] = m_ppExtents[idx]->GetFullPath();		//		//	FATAL conflicts		//		if (sec0_0->Version != sec0->Version) {			cbparams[1] = (PVOID)sec0_0->Version;			cbparams[3] = (PVOID)sec0->Version;			VDiskCallBack(VDISK_CB_CONF_FILEVER, cbparams);			fatal = TRUE;		}		if (sec0_0->Flags != sec0->Flags) {			cbparams[1] = (PVOID)sec0_0->Flags;			cbparams[3] = (PVOID)sec0->Flags;			VDiskCallBack(VDISK_CB_CONF_FLAGS, cbparams);			fatal = TRUE;		}		if (sec3_0->FilesPerDisk != sec3->FilesPerDisk) {			cbparams[1] = (PVOID)sec3_0->FilesPerDisk;			cbparams[3] = (PVOID)sec3->FilesPerDisk;			VDiskCallBack(VDISK_CB_CONF_EXTENTS, cbparams);			fatal = TRUE;		}		if (sec3_0->DiskCapacity != sec3->DiskCapacity) {			cbparams[1] = (PVOID)sec3_0->DiskCapacity;			cbparams[3] = (PVOID)sec3->DiskCapacity;			VDiskCallBack(VDISK_CB_CONF_CAPACITY, cbparams);			fatal = TRUE;		}		if (!COWD_IS_ROOT(sec0_0->Flags)) {			if (sec0_0->Capacity != sec0->Capacity) {				cbparams[1] = (PVOID)sec0_0->Capacity;				cbparams[3] = (PVOID)sec0->Capacity;				VDiskCallBack(VDISK_CB_CONF_CAPACITY, cbparams);				fatal = TRUE;			}			if (VdkCmpNoCase(sec0_0->u.ParentPath, sec0->u.ParentPath)) {				cbparams[1] = sec0_0->u.ParentPath;				cbparams[3] = sec0->u.ParentPath;				VDiskCallBack(VDISK_CB_CONF_PARENTPATH, cbparams);				fatal = TRUE;			}		}		//		//	Errors which can be ignored		//		if (sec2_0->ParentTS != sec2->ParentTS) {			cbparams[1] = (PVOID)sec2_0->ParentTS;			cbparams[3] = (PVOID)sec2->ParentTS;			VDiskCallBack(VDISK_CB_CONF_PARENTTS, cbparams);			conflict = TRUE;		}		if (sec2_0->TimeStamp != sec2->TimeStamp) {			cbparams[1] = (PVOID)sec2_0->TimeStamp;			cbparams[3] = (PVOID)sec2->TimeStamp;			VDiskCallBack(VDISK_CB_CONF_TIMESTAMP, cbparams);			conflict = TRUE;		}		if (sec3_0->Controller != sec3->Controller) {			cbparams[1] = &sec3_0->Controller;			cbparams[3] = &sec3->Controller;			VDiskCallBack(VDISK_CB_CONF_CONTROLLER, cbparams);			conflict = TRUE;		}		if (sec3_0->Cylinders	!= sec3->Cylinders) {			cbparams[1] = (PVOID)sec3_0->Cylinders;			cbparams[3] = (PVOID)sec3->Cylinders;			VDiskCallBack(VDISK_CB_CONF_CYLINDERS, cbparams);			conflict = TRUE;		}		if (sec3_0->Tracks != sec3->Tracks) {			cbparams[1] = (PVOID)sec3_0->Tracks;			cbparams[3] = (PVOID)sec3->Tracks;			VDiskCallBack(VDISK_CB_CONF_TRACKS, cbparams);			conflict = TRUE;		}		if (sec3_0->Sectors != sec3->Sectors) {			cbparams[1] = (PVOID)sec3_0->Sectors;			cbparams[3] = (PVOID)sec3->Sectors;			VDiskCallBack(VDISK_CB_CONF_SECTORS, cbparams);			conflict = TRUE;		}		if (sec3_0->SequenceNumber != sec3->SequenceNumber) {			cbparams[1] = (PVOID)sec3_0->SequenceNumber;			cbparams[3] = (PVOID)sec3->SequenceNumber;			VDiskCallBack(VDISK_CB_CONF_SEQNUM, cbparams);			conflict = TRUE;		}		if (sec3_0->HardwareVer != sec3->HardwareVer) {			cbparams[1] = (PVOID)sec3_0->HardwareVer;			cbparams[3] = (PVOID)sec3->HardwareVer;			VDiskCallBack(VDISK_CB_CONF_HARDWARE, cbparams);			conflict = TRUE;		}		if (sec3_0->ToolsFlag != sec3->ToolsFlag) {			cbparams[1] = (PVOID)sec3_0->ToolsFlag;			cbparams[3] = (PVOID)sec3->ToolsFlag;			VDiskCallBack(VDISK_CB_CONF_TOOLSFLAG, cbparams);			conflict = TRUE;		}		if (fatal) {			return VDK_DATA;		}		if (conflict) {			if (!VDiskCallBack(VDISK_CB_CONFLICT_IGNORE, NULL)) {				return VDK_CANCEL;			}			SetFlag(VDISK_FLAG_DIRTY);		}	}	//	//	store necessary disk parameters	//	if (COWD_IS_ROOT(sec0_0->Flags)) {		ClrFlag(VDISK_FLAG_CHILD);		if (COWD_IS_MULTI(sec0_0->Flags)) {			m_nCapacity		= sec3_0->DiskCapacity;			m_nCylinders	= sec3_0->Cylinders;			m_nTracks		= sec3_0->Tracks;			m_nSectors		= sec3_0->Sectors;		}		else {			m_nCapacity		= sec0_0->Capacity;			m_nCylinders	= sec0_0->u.Geometry.Cylinders;			m_nTracks		= sec0_0->u.Geometry.Tracks;			m_nSectors		= sec0_0->u.Geometry.Sectors;		}	}	else {		SetFlag(VDISK_FLAG_CHILD);		m_nCapacity = sec0_0->Capacity;		StoreParentPath(sec0_0->u.ParentPath);		if ((isalpha(*m_pParentPath) && *(m_pParentPath + 1) == ':') ||			*m_pParentPath == PATH_SEPARATOR_CHAR ||			*m_pParentPath == ALT_SEPARATOR_CHAR) {			SetFlag(VDISK_FLAG_ABSPATH);		}		else {			ClrFlag(VDISK_FLAG_ABSPATH);		}	}	m_nParentTS		= sec2_0->ParentTS;	m_nTimeStamp	= sec2_0->TimeStamp;	m_nHardwareVer	= sec3_0->HardwareVer;	m_nToolsFlag	= sec3_0->ToolsFlag;	if (sec3_0->Controller == COWD_CONTROLLER_IDE) {		m_nController	= VDISK_CONTROLLER_IDE;	}	else {		m_nController	= VDISK_CONTROLLER_SCSI;	}	//	// adjust file capacity of the last extent	// -- cowd header does not explicitly specify it.	//	total_sectors = 0;	for (idx = 0; idx < m_nExtents - 1; idx++) {		total_sectors += m_ppExtents[idx]->GetCapacity();	}	if (total_sectors >= m_nCapacity) {		CHAR path[MAX_PATH];		cbparams[0] = path;		cbparams[1] = (PVOID)m_nCapacity;		cbparams[2] = (PVOID)total_sectors;		FullPath(path);		if (!VDiskCallBack(VDISK_CB_COWD_CAPACITY, cbparams)) {			return VDK_DATA;		}		if (total_sectors >= m_nCapacity) {			return VDK_DATA;		}		SetFlag(VDISK_FLAG_DIRTY);	}	m_ppExtents[idx]->SetCapacity(m_nCapacity - total_sectors);	//	//	Update ?	//	if (m_nFlags & VDISK_FLAG_DIRTY) {		CHAR path[MAX_PATH];		cbparams[0] = path;		FullPath(path);		if (VDiskCallBack(VDISK_CB_CONFIRM_FIX, cbparams)) {			for (idx = 0; idx < m_nExtents; idx++) {				ret = m_ppExtents[idx]->Update();				if (ret != VDK_OK) {					return ret;				}			}		}		ClrFlag(VDISK_FLAG_DIRTY);	}	return VDK_OK;}////	Create VMware 2/3 virtual disk//VDKSTAT VDiskCowd::Create(ULONG flags){	ULONG idx;	VDKSTAT ret = VDK_OK;	if (!m_nExtents || !m_ppExtents || !m_ppExtents[0]) {		return VDK_FUNCTION;	}	for (idx = 0; idx < m_nExtents; idx++) {		VDiskExtCowd *ext = (VDiskExtCowd *)m_ppExtents[idx];		ext->CreateHeader(this, idx);		ret = ext->Create(flags);		if (ret != VDK_OK) {			break;		}	}	return ret;}////	Creates a new extent object for this instance//VDiskExt *VDiskCowd::NewExtent(){	return new VDiskExtCowd;}////	Get path for each extent files//void VDiskCowd::GetExtentPath(	PCHAR pPath, ULONG nSeq){	if (nSeq) {		sprintf(pPath, "%s" PATH_SEPARATOR_STR "%s-%02ld.%s",			m_pPath, m_pBody, nSeq + 1, m_pExtension);	}	else {		sprintf(pPath, "%s" PATH_SEPARATOR_STR "%s.%s",			m_pPath, m_pBody, m_pExtension);	}}////	Set default geometry values//void VDiskCowd::SetGeometry(){	if (m_nController == VDISK_CONTROLLER_IDE) {		if (m_nVMwareVer == 2) {			m_nTracks	= COWD1_TRACKS_IDE;			m_nSectors	= COWD_SECTORS_IDE;		}		else {			m_nTracks	= COWD3_TRACKS_IDE;			m_nSectors	= COWD_SECTORS_IDE;		}	}	else {		if (m_nCapacity <=			COWD_SECTORS_SCSI_1023M * COWD_TRACKS_SCSI_1023M * 1023) {			m_nSectors	= COWD_SECTORS_SCSI_1023M;			m_nTracks	= COWD_TRACKS_SCSI_1023M;		}		else if (m_nCapacity <=			COWD_SECTORS_SCSI_2046M * COWD_TRACKS_SCSI_2046M * 1023) {			m_nSectors	= COWD_SECTORS_SCSI_2046M;			m_nTracks	= COWD_TRACKS_SCSI_2046M;		}		else {			m_nSectors	= COWD_SECTORS_SCSI_LARGE;			m_nTracks	= COWD_TRACKS_SCSI_LARGE;		}	}	m_nCylinders = m_nCapacity / (m_nSectors * m_nTracks);}////	Get default extent size//ULONG VDiskCowd::DefaultExtSize(){	ULONG ext_size = 0;	if (m_nVMwareVer == 2) {		if (m_nController == VDISK_CONTROLLER_SCSI) {			ext_size = COWD1_MAX_EXTENT_SCSI;		}		else if (m_nController == VDISK_CONTROLLER_IDE) {			ext_size = COWD1_MAX_EXTENT_IDE;		}	}	else {		ext_size = COWD3_MAX_EXTENT_SPARSE;	}	if (m_nCapacity > ext_size) {		if (m_nVMwareVer == 2) {			//			//	VMware 2.x doesn't allow multi-extent virutal disk			//			ext_size = 0;		}		else {			ext_size = m_nCapacity;		}	}	return ext_size;}

⌨️ 快捷键说明

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