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

📄 vdiskutil.cpp

📁 Virtual Disk Driver
💻 CPP
字号:
/*	VDiskUtil.cpp	Virtual Disk utility functions	Copyright (C) 2003 Ken Kato*/#include "vdkbase.h"#include "vdkutil.h"#include "vdkfile.h"#include "cowdisk.h"#include "vmdisk.h"#include "VDisk.h"#include "VDiskPlain.h"#include "VDiskCowd.h"#include "VDiskVmdk.h"#include "VDiskSimple.h"#include "VDiskRaw.h"#include "VDiskExt.h"#include "VDiskUtil.h"////	CallBack function pointer and default CallBack//static ULONG DefCallBack(ULONG reason, PVOID *params){	UNREFERENCED_PARAMETER(reason);	UNREFERENCED_PARAMETER(params);	return 0;}VDISK_CALLBACK VDiskCallBack = DefCallBack;void VDiskSetCallBack(VDISK_CALLBACK cb){	VDiskCallBack = cb ? cb : DefCallBack;}////	Initialize from an existing virtual disk file//VDKSTAT VDiskLoadFile(	PVOID *ppDisk,	PCHAR pPath,	PCHAR pBase){	VDisk	*pDisk;	UCHAR	buf[512];	CHAR	path[MAX_PATH];	HANDLE	hFile;	INT64	size;	ULONG	len;	PCHAR	p;	VDKSTAT	ret;	if (!ppDisk || !pPath || !*pPath) {		return VDK_PARAM;	}	*ppDisk = pDisk = NULL;	//	// Open the file	//	strcpy(path, pPath);	ret = VDiskSearchFile(&hFile, path, pBase);	if (ret != VDK_OK) {		return ret;	}	//	//	read first 512 bytes of the file	//	VdkZeroMem(buf, sizeof(buf));	ret = VdkReadFileAt(hFile, 0, buf, sizeof(buf), &len);	if (ret != VDK_OK) {		VdkCloseFile(hFile);		return ret;	}	//	//	get file size	//	ret = VdkGetFileSize(hFile, &size);	if (ret != VDK_OK) {		VdkCloseFile(hFile);		return ret;	}	VdkCloseFile(hFile);	//	//	Identify the file type	//	if (*(PULONG)buf == COWD_SIGNATURE) {		//	VMware 2 or 3 virtual disk		if ((pDisk = new VDiskCowd) == NULL) {			return VdkLastError();		}		goto initialize;	}	if (*(PULONG)buf == VMDK_SIGNATURE) {		//	VMware 4 virtual disk extent file		if ((pDisk = new VDiskVmdk) == NULL) {			return VdkLastError();		}		goto initialize;	}	//	//	does the file contain control character?	//	while (len--) {		if (buf[len] <= 0x08 ||			buf[len] == 0x0b ||			buf[len] == 0x0c ||			(buf[len] >= 0x0e && buf[len] <= 0x1f) ||			buf[len] == 0x7f) {			//	contains a control character			//	-- cannot be a descriptor file			goto simple_disk;		}	}	//	does not contain a control character	//	-- one of descriptor file types	p = (PCHAR)buf;	buf[sizeof(buf) - 1] = '\0';	while (*p) {		while (*p == ' ' || *p == '\t') {			p++;		}		if (!VdkCmpNoCaseN(p, "#vm|TOOLSVERSION",	16) ||			!VdkCmpNoCaseN(p, "#vm|VERSION",		11) ||			!VdkCmpNoCaseN(p, "DRIVETYPE",			 9) ||			!VdkCmpNoCaseN(p, "CYLINDERS",			 9) ||			!VdkCmpNoCaseN(p, "HEADS",				 5) ||			!VdkCmpNoCaseN(p, "SECTORS",			 7) ||			!VdkCmpNoCaseN(p, "ACCESS",				 6)) {			//			//	The file has VMware 2 plain disk entry			//			if ((pDisk = new VDiskPlain) == NULL) {				return VdkLastError();			}			goto initialize;		}		else if (			!VdkCmpNoCaseN(p, "# Disk DescriptorFile",	21) ||			!VdkCmpNoCaseN(p, "version",				 7) ||			!VdkCmpNoCaseN(p, "CID",					 3) ||			!VdkCmpNoCaseN(p, "parentCID",				 9) ||			!VdkCmpNoCaseN(p, "createType",				10) ||			!VdkCmpNoCaseN(p, "parentFileNameHint",		18) ||			!VdkCmpNoCaseN(p, "# Extent description",	20) ||			!VdkCmpNoCaseN(p, "RW",						 2) ||			!VdkCmpNoCaseN(p, "# The Disk Data Base",	20) ||			!VdkCmpNoCaseN(p, "#DDB",					 4) ||			!VdkCmpNoCaseN(p, "ddb.geometry.sectors",	20) ||			!VdkCmpNoCaseN(p, "ddb.geometry.heads",		18) ||			!VdkCmpNoCaseN(p, "ddb.geometry.cylinders",	22) ||			!VdkCmpNoCaseN(p, "ddb.adapterType",		15) ||			!VdkCmpNoCaseN(p, "ddb.virtualHWVersion",	20) ||			!VdkCmpNoCaseN(p, "ddb.toolsVersion",		16)) {			//			//	The file has VMware 4 descriptor file entry			//			if ((pDisk = new VDiskVmdk) == NULL) {				return VdkLastError();			}			goto initialize;		}		//		//	skip to next line		//		while (*(p++) != '\n')			;	}	//	//	not a VMware descriptor file	//	-- raw descriptor	//	if ((pDisk = new VDiskRaw) == NULL) {		return VdkLastError();	}	goto initialize;simple_disk:	//	//	None of above file type	//	{		PVOID param = path;		if (!VDiskCallBack(VDISK_CB_FILE_TYPE, &param)) {			return VDK_CANCEL;		}	}	//	//	generic flat sector image file	//	if ((pDisk = new VDiskSimple) == NULL) {		return VdkLastError();	}initialize:	ret = pDisk->Initialize(path);#ifdef VDK_DEBUG	pDisk->Dump();#endif	*ppDisk = pDisk;	return ret;}////	Create a virtual disk tree//VDKSTAT VDiskCreateTree(PVOID pDisk){	return ((VDisk *)pDisk)->CreateTree();}////	Create a REDO log for a virtual disk//VDKSTAT VDiskCreateRedo(PVOID *ppDisk){	VDKSTAT ret;	VDisk *disk, *redo;	CHAR path[MAX_PATH];	disk = (VDisk *)*ppDisk;	sprintf(path, "%s" PATH_SEPARATOR_STR "%s.%s.REDO",		disk->GetPath(), disk->GetBody(), disk->GetExt());	if (disk->GetVMwareVer() == 4) {		redo = new VDiskVmdk;	}	else {		redo = new VDiskCowd;	}	if (!redo) {		return VdkLastError();	}	ret = redo->InitChild(		VDISK_FLAG_SPARSE | VDISK_FLAG_CHILD,	// | VDISK_FLAG_ABSPATH,		path, disk->GetVMwareVer(), disk);	if (ret != VDK_OK) {		delete redo;		return ret;	}	ret = redo->Create(0);	if (ret != VDK_OK) {		delete redo;		return ret;	}	*ppDisk = redo;	return VDK_OK;}////	Delete VDisk Tree//VOID VDiskDelete(PVOID pDisk){	if (pDisk) {		((VDisk *)pDisk)->DeleteTree();	}}////	Search file//VDKSTAT VDiskSearchFile(HANDLE *pFile, PCHAR pPath, PCHAR pBase){	CHAR	path[MAX_PATH];	VDKSTAT	ret;	//	//	remove leading ".\"	//	while (*pPath == '.' && (		*(pPath + 1) == ALT_SEPARATOR_CHAR ||		*(pPath + 1) == PATH_SEPARATOR_CHAR)) {		memmove(pPath, pPath + 2, strlen(pPath + 2) + 1);	}	//	//	try to open with given path	//	ret = VdkOpenFile(pFile, pPath, strlen(pPath), TRUE);	if (ret == VDK_OK) {		return ret;	}	if ((ret == VDK_NOFILE || ret == VDK_NOPATH) && pBase) {		//		//	Try given base path		//		PCHAR	body;		if ((isalpha(*pPath) && *(pPath + 1) == ':') ||			*pPath == PATH_SEPARATOR_CHAR ||			*pPath == ALT_SEPARATOR_CHAR) {			//			//	absolute path -- extract filename only			//			body = pPath + strlen(pPath);			while (body > pPath &&				*(body - 1) != PATH_SEPARATOR_CHAR &&				*(body - 1) != ALT_SEPARATOR_CHAR) {				body--;			}		}		else {			//			//	relative path -- use as it is			//			body = pPath;		}		sprintf(path, "%s" PATH_SEPARATOR_STR "%s", pBase, body);		//	shouldn't modify 'ret' variable here		if (VdkOpenFile(pFile, path, strlen(path), TRUE) == VDK_OK) {			strcpy(pPath, path);			return VDK_OK;		}	}	//	//	ask user	//	strcpy(path, pPath);	do {		PVOID cbparams[2];		cbparams[0] = path;		cbparams[1] = (PVOID)ret;		if (!VDiskCallBack(VDISK_CB_FILE_OPEN, cbparams)) {			return ret;		}		ret = VdkOpenFile(pFile, path, strlen(path), TRUE);	}	while (ret != VDK_OK);	strcpy(pPath, path);	return ret;}////	Map VDisk attributes to VDK_OPEN_FILE_INFO//VDKSTAT VDiskMapToOpenInfo(	PVOID	pDisk,	PVOID	*ppInfo,	PULONG	pInfoLen){	PVDK_OPEN_FILE_INFO open_info;	PVDK_OPEN_FILE_ITEM open_item;	VDisk *disk;	VDiskExt **ext;	ULONG total_files;	ULONG name_len;	PCHAR name_pos;	ULONG idx;	//	//	Parameter check	//	if (!pDisk || !ppInfo || !pInfoLen) {		return VDK_PARAM;	}	//	//	Find out necessary memory size	//	total_files = 0;	name_len = 0;	disk = (VDisk *)pDisk;	if (disk->GetCylinders() &&		disk->GetTracks() &&		disk->GetSectors()) {		if (disk->GetCylinders() *			disk->GetTracks() *			disk->GetSectors() > disk->GetCapacity()) {			return VDK_PARAM;		}	}	do {		if (!disk->GetExtentCnt()) {			return VDK_PARAM;		}		total_files += disk->GetExtentCnt();		ext = disk->GetExtents();		for (idx = 0; idx < disk->GetExtentCnt(); idx++) {			if (!ext[idx]->GetCapacity() ||				ext[idx]->GetCapacity() > disk->GetCapacity()) {				return VDK_DATA;			}			if (ext[idx]->GetFileAttr() & VDK_INVALID_ATTRIBUTES) {				return VDK_DATA;			}			name_len += strlen(ext[idx]->GetFullPath()) + 1;		}		disk = disk->GetParent();	}	while (disk);	//	//	allocate file information area	//	*pInfoLen = FIELD_OFFSET(VDK_OPEN_FILE_INFO, Files) +		sizeof(VDK_OPEN_FILE_ITEM) * total_files + name_len;	open_info = (PVDK_OPEN_FILE_INFO)VdkAllocMem(*pInfoLen);	if (!open_info) {		return VDK_NOMEMORY;	}	VdkZeroMem(open_info, *pInfoLen);	//	//	Copy file structure into VDK_OPEN_FILE_INFO	//	disk = (VDisk *)pDisk;	open_info->Capacity		= disk->GetCapacity();	open_info->Cylinders	= disk->GetCylinders();	open_info->Tracks		= disk->GetTracks();	open_info->Sectors		= disk->GetSectors();	open_info->FilesTotal	= total_files;	//	//	copy each file information	//	open_item = open_info->Files;	name_pos = (PCHAR)&(open_item[total_files]);	do {		ext = disk->GetExtents();		for (idx = 0; idx < disk->GetExtentCnt(); idx++) {			open_item->FileType = ext[idx]->GetFileType();			open_item->Capacity = ext[idx]->GetCapacity();			strcpy(name_pos, ext[idx]->GetFullPath());			open_item->NameLength = strlen(name_pos) + 1;			name_pos += open_item->NameLength;			open_item++;		}		disk = disk->GetParent();	}	while (disk);	*ppInfo = open_info;	return VDK_OK;}PCHAR	VDiskGetDiskName(PVOID pDisk){	return ((VDisk *)pDisk)->GetBody();}

⌨️ 快捷键说明

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