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

📄 vdisk.cpp

📁 Virtual Disk Driver
💻 CPP
字号:
/*	VDisk.cpp	Virtual Disk base class	Copyright (c) 2003 Ken Kato*/#include "vdkbase.h"#include "vdkutil.h"#include "cowdisk.h"#include "vmdisk.h"#include "VDisk.h"#include "VDiskExt.h"#include "VDiskUtil.h"#include <time.h>////	Constructor//VDisk::VDisk(){	m_pPath			= NULL;	m_pBody			= NULL;	m_pExtension	= NULL;	m_nVMwareVer	= 0;	m_nFlags		= 0;	m_pParentPath	= NULL;	m_pParent		= NULL;	m_nParentTS		= 0;	m_nTimeStamp	= 0;	m_nController	= 0;	m_nHardwareVer	= 0;	m_nToolsFlag	= 0;	m_nCapacity		= 0;	m_nCylinders	= 0;	m_nTracks		= 0;	m_nSectors		= 0;	m_nExtents		= 0;	m_nArraySize	= 0;	m_ppExtents		= NULL;}////	Destructor//VDisk::~VDisk(){	if (m_pPath) {		delete[] m_pPath;	}	if (m_pParentPath) {		delete[] m_pParentPath;	}	if (m_ppExtents) {		while (m_nExtents) {			delete *(m_ppExtents + (--m_nExtents));		}		delete[] m_ppExtents;	}}////	Store full path of given path and//	split it into path, filename, extension//VDKSTAT VDisk::StorePath(PCHAR pPath){	CHAR	path[MAX_PATH];	ULONG	len;	VDKSTAT	ret;	if (!pPath || !*pPath) {		return VDK_PARAM;	}	ret = VdkFullPath(path, sizeof(path), pPath);	if (ret != VDK_OK) {		return ret;	}	len = strlen(path);	//	//	allocate memory and copy path	//	if (m_pPath) {		delete[] m_pPath;	}	if ((m_pPath = new CHAR [len + 1]) == NULL) {		return VdkLastError();	}	strcpy(m_pPath, path);	//	// look for the beginning of extension	//	m_pExtension = m_pPath + len;	while (--m_pExtension > m_pPath &&		*m_pExtension != PATH_SEPARATOR_CHAR &&		*m_pExtension != ALT_SEPARATOR_CHAR) {		if (*m_pExtension == '.') {			if (m_nVMwareVer == 3 && !VdkCmpNoCaseN(m_pExtension, ".redo", 5)) {				//				// Cowd REDO file has double extensions				//				PCHAR p = m_pExtension;				while (--p > m_pPath &&					*p != PATH_SEPARATOR_CHAR &&					*p != ALT_SEPARATOR_CHAR) {					if (!VdkCmpNoCaseN(p, ".vmdk.", 6)) {						m_pExtension = p;						break;					}				}			}			break;		}	}	if (*m_pExtension == '.') {		*(m_pExtension++) = '\0';	}	else {		m_pExtension = m_pPath + len;	}	//	//	Look for the beginning of filename body	//	m_pBody = m_pExtension;	while (--m_pBody > m_pPath) {		if (*m_pBody == PATH_SEPARATOR_CHAR ||			*m_pBody == ALT_SEPARATOR_CHAR) {			*(m_pBody++) = '\0';			break;		}	}	return VDK_OK;}////	Store parent path//VDKSTAT VDisk::StoreParentPath(PCHAR pPath){	ULONG len;	if (m_pParentPath) {		delete[] m_pParentPath;		m_pParentPath = NULL;	}	if (!pPath || !*pPath) {		return VDK_OK;	}	len = strlen(pPath);	if (len) {		if ((m_pParentPath = new CHAR [len + 1]) == NULL) {			return VdkLastError();		}		strcpy(m_pParentPath, pPath);	}	return VDK_OK;}////	Add new extent object to list//VDKSTAT VDisk::AddExtent(VDiskExt *ext){	if (!ext) {		return VDK_PARAM;	}	if (m_nExtents == m_nArraySize) {		VDiskExt **tmp = new VDiskExt *[m_nArraySize + 10];		if (tmp == NULL) {			return VdkLastError();		}		memcpy(tmp, m_ppExtents, sizeof(VDiskExt *) * m_nArraySize);		memset(tmp + m_nArraySize, 0, sizeof(VDiskExt *) * 10);		delete[] m_ppExtents;		m_ppExtents = tmp;		m_nArraySize += 10;	}	m_ppExtents[m_nExtents++] = ext;	return VDK_OK;}////	Create all ancestors//VDKSTAT VDisk::CreateTree(){	VDKSTAT ret;	VDisk *disk;	disk = this;	while (disk->m_nFlags & VDISK_FLAG_CHILD) {		ret = VDiskLoadFile(			(PVOID *)&(disk->m_pParent),			disk->m_pParentPath,			disk->m_pPath);		if (ret != VDK_OK) {			return ret;		}		disk = disk->m_pParent;	}	if (disk != this) {		ULONG cylinders	= disk->m_nCylinders;		ULONG tracks	= disk->m_nTracks;		ULONG sectors	= disk->m_nSectors;		disk = this;		while (disk->m_nFlags & VDISK_FLAG_CHILD) {			//			//	Check parent-child consistency			//			PVOID cbparams[4];			CHAR child_path[MAX_PATH], parent_path[MAX_PATH];			cbparams[0] = child_path;			cbparams[2] = parent_path;			disk->FullPath(child_path);			disk->m_pParent->FullPath(parent_path);			if (disk->m_nCapacity != disk->m_pParent->m_nCapacity) {				//	capacity mismatch				//	-- this is fatal				cbparams[1] = (PVOID)disk->m_nCapacity;				cbparams[3] = (PVOID)disk->m_pParent->m_nCapacity;				VDiskCallBack(VDISK_CB_PARENT_CAPACITY, cbparams);				return VDK_DATA;			}			if (disk->m_nParentTS != disk->m_pParent->m_nTimeStamp) {				//	timestamp mismatch				cbparams[1] = (PVOID)disk->m_nParentTS;				cbparams[3] = (PVOID)disk->m_pParent->m_nTimeStamp;				if (!VDiskCallBack(VDISK_CB_PARENT_TIMESTAMP, cbparams)) {					return VDK_CANCEL;				}			}			if (disk->m_nController &&				disk->m_nController != disk->m_pParent->m_nController) {				//	controller type mismatch				cbparams[1] = (PVOID)disk->m_nController;				cbparams[3] = (PVOID)disk->m_pParent->m_nController;				if (!VDiskCallBack(VDISK_CB_PARENT_CONTROLLER, cbparams)) {					return VDK_CANCEL;				}			}			disk->m_nCylinders	= cylinders;			disk->m_nTracks		= tracks;			disk->m_nSectors	= sectors;			disk = disk->m_pParent;		}	}	return VDK_OK;}////	Delete including all ancestors//void VDisk::DeleteTree(){	VDisk *disk = this;	while (disk) {		VDisk *temp = disk;		disk = disk->m_pParent;		delete temp;	}}////	Initialize as a root disk with parameters//VDKSTAT VDisk::InitRoot(	ULONG		flags,	PCHAR		pPath,	ULONG		version,	ULONG		controller,	ULONG		capacity){	ULONG ext_size;	VDKSTAT ret;	if (!pPath || !*pPath ||		!version || !controller || !capacity) {		return VDK_PARAM;	}	if ((ret = StorePath(pPath)) != VDK_OK) {		return ret;	}	m_nVMwareVer	= version;	m_nFlags		= flags & ~VDISK_FLAG_CHILD;	m_nHardwareVer	= version - 1;	m_nController	= controller;	SetDefaultTS();	//	//	decide geometry values	//	m_nCapacity = capacity;	SetGeometry();	//	//	deside each extent size	//	ext_size = DefaultExtSize();	if (ext_size == 0) {		return VDK_PARAM;	}	//	//	create each extent object	//	ret = CreateExtents(ext_size);	if (ret != VDK_OK) {		return ret;	}#ifdef VDK_DEBUG	Dump();#endif	return ret;}////	Initialize as a child with parameters//VDKSTAT VDisk::InitChild(	ULONG		flags,	PCHAR		pPath,	ULONG		version,	VDisk		*parent){	CHAR path[MAX_PATH];	ULONG ext_size;	VDKSTAT ret;	if (!pPath || !*pPath || !version || !parent) {		return VDK_PARAM;	}	if (!(flags & VDISK_FLAG_SPARSE) ||		!(flags & VDISK_FLAG_CHILD)) {		return VDK_PARAM;	}	if (version < parent->GetVMwareVer()) {		return VDK_PARAM;	}	if ((ret = StorePath(pPath)) != VDK_OK) {		return ret;	}	if ((flags & VDISK_FLAG_ABSPATH) ||		VdkCmpNoCase(m_pPath, parent->m_pPath)) {		sprintf(path, "%s" PATH_SEPARATOR_STR "%s.%s",			parent->m_pPath, parent->m_pBody, parent->m_pExtension);	}	else {		sprintf(path, "%s.%s", parent->m_pBody, parent->m_pExtension);	}	if ((ret = StoreParentPath(path)) != VDK_OK) {		return ret;	}	m_pParent		= parent;	m_nVMwareVer	= version;	m_nFlags		= flags;	m_nCapacity		= parent->GetCapacity();	m_nCylinders	= parent->GetCylinders();	m_nTracks		= parent->GetTracks();	m_nSectors		= parent->GetSectors();	m_nController	= parent->GetController();	m_nParentTS		= parent->GetTimeStamp();	m_nTimeStamp	= time(NULL);	ext_size		= m_nCapacity;	if (m_nVMwareVer >= 3) {		m_nToolsFlag	= parent->GetToolsFlag();		m_nHardwareVer	= parent->GetHardwareVer();		if (m_nVMwareVer == 3) {			if (ext_size > COWD3_MAX_EXTENT_SPARSE) {				ext_size = COWD3_MAX_EXTENT_SPARSE;			}		}		else if (m_nVMwareVer == 4) {			if (!(m_nFlags & VDISK_FLAG_SINGLE) &&				ext_size > VMDK_MAX_EXTENT_SPARSE) {				ext_size = VMDK_MAX_EXTENT_SPARSE;			}		}	}	//	//	create each extent objects	//	ret = CreateExtents(ext_size);	if (ret != VDK_OK) {		return ret;	}#ifdef VDK_DEBUG	Dump();#endif	return ret;}////	Create extent objects//VDKSTAT VDisk::CreateExtents(ULONG ext_size){	CHAR	path[MAX_PATH];	VDiskExt *ext;	ULONG	total_size = 0;	VDKSTAT	ret = VDK_OK;	while (total_size < m_nCapacity) {		GetExtentPath(path, m_nExtents);		ext = NewExtent();		if (!ext) {			return VdkLastError();		}		ret = AddExtent(ext);		if (ret != VDK_OK) {			delete ext;			return ret;		}		ret = ext->SetPath(path);		if (ret != VDK_OK) {			return ret;		}		ext->SetCapacity(ext_size);		total_size += ext_size;		if (ext_size > m_nCapacity - total_size) {			ext_size = m_nCapacity - total_size;		}	}	return ret;}////	Set default Timestamp values//void VDisk::SetDefaultTS(){	m_nParentTS	= 0;	m_nTimeStamp = time(NULL);}////	Set geometry values//void VDisk::SetGeometry(){	m_nCylinders	= 0;	m_nTracks		= 0;	m_nSectors		= 0;}////	Returns default (maximum) capacity for a single extension//ULONG VDisk::DefaultExtSize(){	return 0;}#ifdef VDK_DEBUG////	dump virtual disk information//void VDisk::Dump(){	VDKTRACE(VDKINFO,		("%s" PATH_SEPARATOR_STR "%s.%s\n", m_pPath, m_pBody, m_pExtension));	VDKTRACE(VDKINFO,		("VMware %u.x\n", m_nVMwareVer));	char buf[200];	buf[0] = '\0';	if (m_nFlags & VDISK_FLAG_SINGLE) {		strcat(buf, "SINGLE ");	}	else {		strcat(buf, "SPLIT ");	}	if (m_nFlags & VDISK_FLAG_SPARSE) {		strcat(buf, "SPARSE ");	}	else {		strcat(buf, "SOLID ");	}	if (m_nFlags & VDISK_FLAG_ABSPATH) {		strcat(buf, "ABSPATH ");	}	else {		strcat(buf, "RELPATH ");	}	if (m_nFlags & VDISK_FLAG_CHILD) {		strcat(buf, "CHILD ");	}	else {		strcat(buf, "ROOT ");	}	if (m_nFlags & VDISK_FLAG_DIRTY) {		strcat(buf, "MODIFIED");	}	VDKTRACE(VDKINFO,		("%s\n", buf));	//	//	Virtual disk parameters	//	VDKTRACE(VDKINFO,("ParentPath: %s\n", m_pParentPath));	VDKTRACE(VDKINFO,("Capacity  : %lu\n", m_nCapacity));	VDKTRACE(VDKINFO,("Cylinders : %lu\n", m_nCylinders));	VDKTRACE(VDKINFO,("Tracks    : %lu\n", m_nTracks));	VDKTRACE(VDKINFO,("Sectors   : %lu\n", m_nSectors));	VDKTRACE(VDKINFO,("Parent TS : 0x%08x\n", m_nParentTS));	VDKTRACE(VDKINFO,("TimeStamp : 0x%08x\n", m_nTimeStamp));	if (m_nController == VDISK_CONTROLLER_SCSI) {		VDKTRACE(VDKINFO,("Controller: SCSI\n"));	}	else if (m_nController == VDISK_CONTROLLER_IDE) {		VDKTRACE(VDKINFO,("Controller: IDE\n"));	}	else {		VDKTRACE(VDKINFO,("Controller: Unknown (%d)\n", m_nController));	}	VDKTRACE(VDKINFO,("Hardware  : %lu\n", m_nHardwareVer));	VDKTRACE(VDKINFO,("ToolsFlag : 0x%08x\n", m_nToolsFlag));	for (ULONG idx = 0; idx < m_nExtents; idx++) {		VDiskExt *ext = m_ppExtents[idx];		if (ext) {			VDKTRACE(VDKINFO,("\nExtent #%lu\n", idx));			VDKTRACE(VDKINFO,("Path      : %s\n", ext->GetFullPath()));			VDKTRACE(VDKINFO,("Capacity  : %lu\n", ext->GetCapacity()));			VDKTRACE(VDKINFO,("FileSize  : %" INT64_PRINT_FORMAT "u\n", ext->GetFileSize()));		}	}	VDKTRACE(VDKINFO,("========================================\n\n"));}#endif	//	VDK_DEBUG

⌨️ 快捷键说明

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