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

📄 vdiskplain.cpp

📁 Virtual Disk Driver
💻 CPP
字号:
/*	VDiskPlain.cpp	Plain disk class	Copyright (c) 2003 Ken Kato*/#include "vdkbase.h"#include "vdkutil.h"#include "cowdisk.h"#include "VDiskPlain.h"#include "VDiskExtRaw.h"#include "VDiskUtil.h"#include "VDiskFile.h"////	Constructor -- set default members//VDiskPlain::VDiskPlain(){	m_nVMwareVer	= 2;	m_nHardwareVer	= COWD_HARDWARE_VMWARE2;}////	Destructor//VDiskPlain::~VDiskPlain(){}////	Initialize instance from a VMware 2.x plain disk descriptor file//VDKSTAT VDiskPlain::Initialize(PCHAR pPath){	VDiskFile file;	CHAR	buf[MAX_PATH + 40];	CHAR	path[MAX_PATH];	PCHAR	current;	VDKSTAT	ret;	PVOID	cbparams[2];	//	//	parameter check	//	if (!pPath || !*pPath) {		return VDK_PARAM;	}	//	//	store path	//	if ((ret = StorePath(pPath)) != VDK_OK) {		return ret;	}	//	//	open file	//	if ((ret = file.Open(pPath)) != VDK_OK) {		return ret;	}	//	//	initialize members	//	ClrFlag(VDISK_FLAG_CHILD);	cbparams[0] = pPath;	while ((ret = file.ReadText(buf, sizeof(buf), NULL)) == VDK_OK) {		//		//	replace tabs with blanks		//		current = buf;		while (*current) {			if (*current == '\t' || *current == '\n') {				*current = ' ';			}			current++;		}		//		//	remove trailing blanks		//		while (current > buf && *(--current) == ' ') {			*current = '\0';		}		//		//	skip leading blanks		//		current = buf;		while (*current == ' ') {			current++;		}		//		//	blank line?		//		if (!*current) {			continue;		}		cbparams[1] = current;		//		//	start parsing		//		if (!VdkCmpNoCaseN(current, "ACCESS ", 7)) {			VDiskExtRaw *ext;			PCHAR	top, tail;			ULONG	capacity;			ULONG	offset;			CHAR	delim;			HANDLE	hFile;			//			//	search path field			//			top = current + 7;			while (*top == ' ') {				top++;			}			if (*top == '\"') {				delim = '\"';				top++;			}			else {				delim = ' ';			}			tail = top;			while (*tail && *tail != delim) {				tail++;			}			if (!*tail || tail - top >= MAX_PATH) {				if (!VDiskCallBack(VDISK_CB_DESC_BADENTRY, cbparams)) {					return VDK_CANCEL;				}				SetFlag(VDISK_FLAG_DIRTY);				continue;			}			if ((isalpha(*top) && *(top + 1) == ':') ||				*top == PATH_SEPARATOR_CHAR ||				*top == ALT_SEPARATOR_CHAR) {				SetFlag(VDISK_FLAG_ABSPATH);			}			else {				ClrFlag(VDISK_FLAG_ABSPATH);			}			VdkCopyMem(path, top, tail - top);			path[tail - top] = '\0';			//			//	search offset field			//			top = tail + 1;			while (*top == ' ') {				top++;			}			if (isdigit(*top)) {				offset = atol(top);			}			else {				offset = VDiskCallBack(					VDISK_CB_DESC_OFFSET, cbparams);				if (offset == (ULONG)-1) {					return VDK_DATA;				}				SetFlag(VDISK_FLAG_DIRTY);			}			//			//	search capacity field			//			while (isdigit(*top)) {				top++;			}			while (*top == ' ') {				top++;			}			capacity = atol(top);			if (!capacity) {				capacity = VDiskCallBack(					VDISK_CB_DESC_CAPACITY, cbparams);				if (!capacity) {					return VDK_DATA;				}				SetFlag(VDISK_FLAG_DIRTY);			}			//			//	create an extent object			//			ext = new VDiskExtRaw;			if (ext == NULL) {				return VdkLastError();			}			ret = AddExtent(ext);			if (ret != VDK_OK) {				delete ext;				return ret;			}			ret = VDiskSearchFile(&hFile, path, m_pPath);			if (ret != VDK_OK) {				return ret;			}			ret = ext->SetPath(path);			if (ret != VDK_OK) {				return ret;			}			ret = ext->Load(hFile);			VdkCloseFile(hFile);			if (ret != VDK_OK) {				return ret;			}			ext->SetCapacity(capacity);			ext->SetStartOffset(offset);		}		else if (!VdkCmpNoCaseN(current, "CYLINDERS ", 10)) {			m_nCylinders = atol(current + 10);			if (!m_nCylinders) {				m_nCylinders = VDiskCallBack(					VDISK_CB_DESC_GEOMETRY, cbparams);				if (!m_nCylinders) {					return VDK_DATA;				}				SetFlag(VDISK_FLAG_DIRTY);			}		}		else if (!VdkCmpNoCaseN(current, "HEADS ", 6)) {			m_nTracks = atol(current + 6);			if (!m_nTracks) {				m_nTracks = VDiskCallBack(					VDISK_CB_DESC_GEOMETRY, cbparams);				if (!m_nTracks) {					return VDK_DATA;				}				SetFlag(VDISK_FLAG_DIRTY);			}		}		else if (!VdkCmpNoCaseN(current, "SECTORS ", 8)) {			m_nSectors = atol(current + 8);			if (!m_nSectors) {				m_nSectors = VDiskCallBack(					VDISK_CB_DESC_GEOMETRY, cbparams);				if (!m_nSectors) {					return VDK_DATA;				}				SetFlag(VDISK_FLAG_DIRTY);			}		}		else if (!VdkCmpNoCaseN(current, "DRIVETYPE ", 10)) {			PCHAR p = current + 10;			while (*p == ' ') {				p++;			}			if (!VdkCmpNoCase(p, "scsi")) {				m_nController = VDISK_CONTROLLER_SCSI;			}			else if (!VdkCmpNoCase(p, "ide")) {				m_nController = VDISK_CONTROLLER_IDE;			}			else {				m_nController = VDiskCallBack(					VDISK_CB_CONTROLLER, cbparams);				if (m_nController != VDISK_CONTROLLER_SCSI &&					m_nController != VDISK_CONTROLLER_IDE) {					return VDK_CANCEL;				}				SetFlag(VDISK_FLAG_DIRTY);			}		}		else if (!VdkCmpNoCaseN(current, "#vm|TOOLSVERSION ", 17)) {			m_nVMwareVer = 3;			m_nToolsFlag = atol(current + 17);		}		else if (!VdkCmpNoCaseN(current, "#vm|VERSION ", 12)) {			m_nVMwareVer = 3;			m_nHardwareVer = atol(current + 12);			if (m_nHardwareVer != COWD_HARDWARE_VMWARE2 &&				m_nHardwareVer != COWD_HARDWARE_VMWARE3 &&				m_nHardwareVer != COWD_HARDWARE_VMWARE4) {				m_nHardwareVer = VDiskCallBack(					VDISK_CB_HARDWAREVER, cbparams);				if (m_nHardwareVer != COWD_HARDWARE_VMWARE2 &&					m_nHardwareVer != COWD_HARDWARE_VMWARE3 &&					m_nHardwareVer != COWD_HARDWARE_VMWARE4) {					return VDK_CANCEL;				}				SetFlag(VDISK_FLAG_DIRTY);			}		}		else if (*current != '#') {			if (!VDiskCallBack(VDISK_CB_DESC_BADENTRY, cbparams)) {				return VDK_CANCEL;			}			SetFlag(VDISK_FLAG_DIRTY);		}	}	file.Close();	if (ret == VDK_EOF) {		ret = Check();	}	return ret;}////	Initialize as a child disk//VDKSTAT VDiskPlain::InitChild(	ULONG		flags,	PCHAR		pPath,	ULONG		version,	VDisk		*parent){	UNREFERENCED_PARAMETER(flags);	UNREFERENCED_PARAMETER(pPath);	UNREFERENCED_PARAMETER(version);	UNREFERENCED_PARAMETER(parent);	//	//	Plain Disk cannot be a child	//	return VDK_FUNCTION;}////	Check paramters//VDKSTAT VDiskPlain::Check(){	CHAR	path[MAX_PATH];	PVOID	cbparams[3];	ULONG	idx;	VDKSTAT ret;	FullPath(path);	//	//	At least one extent must be present	//	if (!m_nExtents) {		cbparams[0] = path;		VDiskCallBack(VDISK_CB_EMPTY_IMAGE, cbparams);		return VDK_DATA;	}	//	//	Check extent offset	//	m_nCapacity		= 0;	for (idx = 0; idx < m_nExtents; idx++) {		VDiskExtRaw *ext = (VDiskExtRaw *)m_ppExtents[idx];		if (ext->GetStartOffset() != m_nCapacity) {			cbparams[0] = ext->GetFullPath();			cbparams[1] = (PVOID)ext->GetStartOffset();			cbparams[2] = (PVOID)m_nCapacity;			//			//	file range conflict or there is a hole			//			if (!VDiskCallBack(VDISK_CB_EXT_OFFSET, cbparams)) {				return VDK_CANCEL;			}			ext->SetStartOffset(m_nCapacity);			SetFlag(VDISK_FLAG_DIRTY);		}		if ((ret = ext->Check()) != VDK_OK) {			return ret;		}		if (ext->IsModified()) {			SetFlag(VDISK_FLAG_DIRTY);		}		m_nCapacity += ext->GetCapacity();	}	cbparams[0] = path;	//	//	Check geometry	//	/*	if (m_nCylinders * m_nTracks * m_nSectors != m_nCapacity) {		cbparams[1] = (PVOID)m_nCapacity;		cbparams[2] = (PVOID)total_size;		if (!VDiskCallBack(VDISK_CB_EXT_CAPACITY, cbparams)) {			return VDK_DATA;		}		m_nCapacity	= total_size;		SetGeometry();		SetFlag(VDISK_FLAG_DIRTY);		for (idx = 0; idx < m_nExtents; idx++) {			if (total_size < m_ppExtents[idx]->GetCapacity()) {				m_ppExtents[idx]->SetCapacity(total_size);				total_size = 0;			}			else {				total_size -= m_ppExtents[idx]->GetCapacity();			}		}	}	*/	//	//	Any bad parameter?	//	if (m_nFlags & VDISK_FLAG_DIRTY) {		if (VDiskCallBack(VDISK_CB_CONFIRM_FIX, cbparams)) {			ret = WriteDescriptor(FALSE, FALSE);			if (ret != VDK_OK) {				return ret;			}			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 plain disk descriptor file and extent files//VDKSTAT VDiskPlain::Create(ULONG flags){	ULONG idx;	VDKSTAT ret;	if (!m_nExtents || !m_ppExtents || !m_ppExtents[0]) {		return VDK_FUNCTION;	}	//	//	create each extent file	//	for (idx = 0; idx < m_nExtents; idx++) {		ret = m_ppExtents[idx]->Create(flags);		if (ret != VDK_OK) {			return ret;		}	}	//	//	create the description file	//	ret = WriteDescriptor(TRUE, (flags & VDISK_CREATE_FORCE));	return ret;}////	Write plain disk descriptor file//VDKSTAT VDiskPlain::WriteDescriptor(BOOL create, BOOL force){	CHAR buf[MAX_PATH + 30];	ULONG idx;	ULONG path_len;	HANDLE hFile = INVALID_HANDLE_VALUE;	VDKSTAT ret = VDK_OK;	//	//	create/open the description file	//	FullPath(buf);	if (create) {		ret = VdkCreateFile(&hFile, buf, force);	}	else {		ret = VdkOpenFile(&hFile, buf, strlen(buf), FALSE);	}	if (ret != VDK_OK) {		return ret;	}	//	//	create header entries	//	buf[0] = '\0';	if (m_nVMwareVer == 3) {		//		//	additional entry for VMware 3.x		//		sprintf(buf,			"#vm|TOOLSVERSION      %lu\n"			"#vm|VERSION           %lu\n",			m_nToolsFlag, m_nHardwareVer);	}	sprintf(buf + strlen(buf),		"DRIVETYPE     %s\n"		"CYLINDERS %6lu\n"		"HEADS     %6lu\n"		"SECTORS   %6lu\n",		m_nController == VDISK_CONTROLLER_IDE ? "ide" : "scsi",		m_nCylinders, m_nTracks, m_nSectors);	ret = VdkWriteFileAt(hFile, -1, buf, strlen(buf), NULL);	if (ret != VDK_OK) {		goto cleanup;	}	//	//	create each extent entry	//	path_len = strlen(m_pPath);	for (idx = 0; idx < m_nExtents; idx++) {		VDiskExtRaw *ext;		PCHAR path;		ext = (VDiskExtRaw *)m_ppExtents[idx];		path = ext->GetFullPath();		if (!(m_nFlags & VDISK_FLAG_ABSPATH) &&			!VdkCmpNoCaseN(m_pPath, path, path_len)) {			path = ext->GetFileName();		}		sprintf(buf, "ACCESS \"%s\" %lu %lu\n",			path, ext->GetStartOffset(), ext->GetCapacity());		ret = VdkWriteFileAt(hFile, -1, buf, strlen(buf), NULL);		if (ret != VDK_OK) {			goto cleanup;		}	}cleanup:	if (hFile != INVALID_HANDLE_VALUE) {		VdkCloseFile(hFile);	}	return ret;}////	Create a new extent object for this instance//VDiskExt *VDiskPlain::NewExtent(){	return new VDiskExtRaw;}////	Get path for each extent files//void VDiskPlain::GetExtentPath(	PCHAR pPath, ULONG nSeq){	sprintf(pPath, "%s" PATH_SEPARATOR_STR "%s%lu.dat",		m_pPath, m_pBody, nSeq + 1);}////	Set default geometry values//void VDiskPlain::SetGeometry(){	if (m_nController == VDISK_CONTROLLER_IDE) {		m_nTracks	= COWD1_TRACKS_IDE_PLAIN;		m_nSectors	= COWD1_SECTORS_IDE_PLAIN;	}	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);}////	Returns default extent size//ULONG VDiskPlain::DefaultExtSize(){	ULONG ext_size = COWD1_MAX_EXTENT_PLAIN;	if (m_nCapacity > ext_size) {		//		//	In VMware 2.x plain disks, all extents are the same size		//		ULONG extents = (m_nCapacity + ext_size - 1) / ext_size;		ext_size = (m_nCapacity + extents - 1) / extents;	}	return ext_size;}

⌨️ 快捷键说明

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