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

📄 vdkopen.c

📁 Virtual Disk Driver
💻 C
📖 第 1 页 / 共 2 页
字号:
/*	vdkopen.c	Virtual Disk open functions	Copyright (C) 2003 Ken Kato*/#include "vdkbase.h"#include "vdkutil.h"#include "vdkfile.h"#include "vdkaccess.h"#include "cowdisk.h"#include "vmdisk.h"////	local functions//static VDKSTAT VdkSetCowdParam(	PVDK_FILE_INFO	DiskInfo,	ULONG			ReadOnly);static VDKSTAT VdkSetVmdkParam(	PVDK_FILE_INFO	DiskInfo,	ULONG			ReadOnly);////	declare pageable functions//#ifdef ALLOC_PRAGMA#pragma alloc_text(PAGE, VdkOpenCheckParam)#pragma alloc_text(PAGE, VdkOpenDisk)#pragma alloc_text(PAGE, VdkSetCowdParam)#pragma alloc_text(PAGE, VdkSetVmdkParam)#endif	// ALLOC_PRAGMA////	Check open file info integrity//VDKSTAT VdkOpenCheckParam(	PVDK_OPEN_FILE_INFO	OpenInfo,	ULONG				InputLen){	ULONG	fixed_size;	ULONG	total_sectors;	ULONG	total_name_len;	ULONG	generation;	ULONG	idx;	//	// check minimum length	//	if (InputLen < sizeof(VDK_OPEN_FILE_INFO)) {		return VDK_BUFFER;	}	//	// check DiskType	//	if (OpenInfo->DiskType != VDK_DISKTYPE_WRITABLE &&		OpenInfo->DiskType != VDK_DISKTYPE_READONLY &&		OpenInfo->DiskType != VDK_DISKTYPE_WRITEBLOCK) {		VDKTRACE(VDKOPEN,			("[VDK] IOCTL_VDK_OPEN_FILE: Invalid DiskType %u\n",			OpenInfo->DiskType));		return VDK_PARAM;	}	//	// There must be at least one file to open	//	if (OpenInfo->FilesTotal == 0 || OpenInfo->Capacity == 0) {		VDKTRACE(VDKOPEN,			("[VDK] IOCTL_VDK_OPEN_FILE: disk size == 0\n"));		return VDK_PARAM;	}	//	// If geometry values are specified, they must be	// consistent with the number of total sectors	//	if (OpenInfo->Cylinders *		OpenInfo->Tracks *		OpenInfo->Sectors > OpenInfo->Capacity) {		VDKTRACE(VDKOPEN,			("[VDK] IOCTL_VDK_OPEN_FILE: geometry / capacity conflict\n"));		return VDK_PARAM;	}	//	// Calculate the minimum necessary size for	// the VDK_OEPN_DISK and all VDK_OPEN_FILE_ITEM structures.	//	fixed_size =		FIELD_OFFSET(VDK_OPEN_FILE_INFO, Files) +		(sizeof(VDK_OPEN_FILE_ITEM) * OpenInfo->FilesTotal);	//	// Recheck input parameter length	// -- large enough to contain all fixed info?	//	if (InputLen < fixed_size) {		return VDK_BUFFER;	}	//	// Check each file info	//	total_sectors = 0;	total_name_len = 0;	generation = 0;	idx = 0;	do {		PVDK_OPEN_FILE_ITEM open_file;		//		// file item to work with		//		open_file = &(OpenInfo->Files[idx]);		//		// check file type		//		if (open_file->FileType != VDK_FILETYPE_NONE &&			open_file->FileType != VDK_FILETYPE_FLAT &&			open_file->FileType != VDK_FILETYPE_COWD &&			open_file->FileType != VDK_FILETYPE_VMDK) {			VDKTRACE(VDKOPEN,				("[VDK] IOCTL_VDK_OPEN_FILE: File #%u Invalid FileType %u\n",				idx, open_file->FileType));			return VDK_PARAM;		}		//		// Top level files cannot be missing if disk is writable		//		if (!generation &&			OpenInfo->DiskType == VDK_DISKTYPE_WRITABLE &&			open_file->FileType == VDK_FILETYPE_NONE) {			VDKTRACE(VDKOPEN,				("[VDK] IOCTL_VDK_OPEN_FILE: Missing top level file #%u\n",				idx));			return VDK_PARAM;		}		//		// check file length		//		if (open_file->Capacity == 0 ||			open_file->Capacity > OpenInfo->Capacity) {			VDKTRACE(VDKOPEN,				("[VDK] IOCTL_VDK_OPEN_FILE: File #%u invalid size %u\n",				idx, open_file->Capacity));			return VDK_PARAM;		}		//		// if the file is not missing, file name must be provided		//		if (open_file->FileType != VDK_FILETYPE_NONE &&			open_file->NameLength == 0) {			VDKTRACE(VDKOPEN,				("[VDK] IOCTL_VDK_OPEN_FILE: File #%u filename required\n",				idx));			return VDK_PARAM;		}		//		// BackOffset can only be used for solid files		//		if (open_file->FileType != VDK_FILETYPE_FLAT &&			open_file->BackOffset != 0) {			VDKTRACE(VDKOPEN,				("[VDK] IOCTL_VDK_OPEN_FILE: File #%u BackOffset #%lu\n",				idx, open_file->BackOffset));			return VDK_PARAM;		}		//		// Sum up the file length and name length		//		total_sectors	+= open_file->Capacity;		total_name_len	+= open_file->NameLength;		//		// completed one generation?		//		if (total_sectors == OpenInfo->Capacity) {			//			// prepare for the next generation			//			generation++;			total_sectors = 0;		}		else if (total_sectors > OpenInfo->Capacity) {			VDKTRACE(VDKOPEN,				("[VDK] IOCTL_VDK_OPEN_FILE: Size mismatch at File #%u\n",				idx));			return VDK_PARAM;		}	}	while (++idx < OpenInfo->FilesTotal);	//	// The last generation is complete?	//	if (total_sectors) {		VDKTRACE(VDKOPEN,			("[VDK] IOCTL_VDK_OPEN_FILE: Size mismatch at File #%u\n",			idx - 1));		return VDK_PARAM;	}	//	// now total name length is known, check buffer length again	//	if (InputLen < fixed_size + total_name_len) {		return VDK_BUFFER;	}	return VDK_OK;}//// Open image file(s)//VDKSTAT	VdkOpenDisk(	PVDK_OPEN_FILE_INFO	OpenFile,	PVDK_DISK_INFO 		DiskInfo){	PCHAR	name_top;	ULONG	name_total;	ULONG	start_sector;	ULONG	generation;	ULONG	read_only;	ULONG	idx;	VDKSTAT	status = VDK_OK;	//	//	store disk information	//	VdkZeroMem(DiskInfo, sizeof(VDK_DISK_INFO));	DiskInfo->DiskType		= OpenFile->DiskType;	DiskInfo->Capacity		= OpenFile->Capacity;	if (OpenFile->Cylinders && OpenFile->Tracks && OpenFile->Sectors) {		DiskInfo->Cylinders	= OpenFile->Cylinders;		DiskInfo->Tracks	= OpenFile->Tracks;		DiskInfo->Sectors	= OpenFile->Sectors;	}	else {		//		// make up suitable values		//		DiskInfo->Sectors	= VDK_SECTORS_PER_TRACK;		DiskInfo->Tracks	= VDK_TRACKS_PER_CYLINDER;		DiskInfo->Cylinders	=			OpenFile->Capacity / VDK_SECTORS_PER_TRACK / VDK_TRACKS_PER_CYLINDER;	}	DiskInfo->FilesTotal	= OpenFile->FilesTotal;	//	// allocate buffer to store file information	//	DiskInfo->Files = (PVDK_FILE_INFO)VdkAllocMem(		sizeof(VDK_FILE_INFO) * OpenFile->FilesTotal);	if (!DiskInfo->Files) {		VDKTRACE(VDKOPEN,			("[VDK] Can't allocate memory for disk info\n"));		status = VDK_NOMEMORY;		goto cleanup_exit;	}	VdkZeroMem(DiskInfo->Files,		sizeof(VDK_FILE_INFO) * OpenFile->FilesTotal);	//	//	process each files	//	name_top = (PCHAR)OpenFile +		FIELD_OFFSET(VDK_OPEN_FILE_INFO, Files) +		(sizeof(VDK_OPEN_FILE_ITEM) * OpenFile->FilesTotal);	name_total		= 0;	start_sector	= 0;	generation		= 0;	read_only		= (OpenFile->DiskType != VDK_DISKTYPE_WRITABLE);	for (idx = 0; idx < DiskInfo->FilesTotal; idx++) {		PVDK_FILE_INFO	file_info = &DiskInfo->Files[idx];		//		// set up basic parameters		//		file_info->FileType		= OpenFile->Files[idx].FileType;		file_info->Capacity		= OpenFile->Files[idx].Capacity;		file_info->NameLength	= OpenFile->Files[idx].NameLength;		file_info->StartSector	= start_sector;		//		// skip "Missing" files		//		if (file_info->FileType == VDK_FILETYPE_NONE) {			goto next_file;		}		//		//	open file		//		status = VdkOpenFile(			&(file_info->FileHandle),			name_top + name_total,			file_info->NameLength,			read_only);		if (!VDKSUCCESS(status)) {			goto cleanup_exit;		}		//		//	check file attributes		//		status = VdkCheckAttribute(			file_info->FileHandle);		if (!VDKSUCCESS(status)) {			goto cleanup_exit;		}		//		//	get file size		//		{			INT64 size;			status = VdkGetFileSize(file_info->FileHandle, &size);			if (!VDKSUCCESS(status)) {				goto cleanup_exit;			}			file_info->EndOfFile = (ULONG)(size >> VDK_BYTE_SHIFT_TO_SECTOR);		}		//		//	prepare type specific parameters		//		if (file_info->FileType == VDK_FILETYPE_FLAT) {			file_info->prm.SolidBackOffset =				OpenFile->Files[idx].BackOffset;			VDKTRACE(VDKOPEN | VDKINFO,				("[VDK] BackOffset    = %lu\n", file_info->prm.SolidBackOffset));		}		else if (file_info->FileType == VDK_FILETYPE_COWD) {			status = VdkSetCowdParam(file_info, read_only);			if (!VDKSUCCESS(status)) {				goto cleanup_exit;			}		}		else if (file_info->FileType == VDK_FILETYPE_VMDK) {			status = VdkSetVmdkParam(file_info, read_only);			if (!VDKSUCCESS(status)) {				goto cleanup_exit;			}		}next_file:		VDKTRACE(VDKOPEN | VDKINFO,			("[VDK] FileType    = %lu\n", file_info->FileType));		VDKTRACE(VDKOPEN | VDKINFO,			("[VDK] StartSector = %lu\n", file_info->StartSector));		VDKTRACE(VDKOPEN | VDKINFO,			("[VDK] Capacity    = %lu\n", file_info->Capacity));		VDKTRACE(VDKOPEN | VDKINFO,			("[VDK] EndOfFile   = %lu\n", file_info->EndOfFile));		//		// calculate next file's start sector		//		start_sector += file_info->Capacity;		//		// sum up name length		//		name_total += file_info->NameLength;		//		// completed one generation?		//		if (start_sector == OpenFile->Capacity) {			start_sector = 0;			generation++;			read_only = TRUE;		}	}	// next file	//	// Store filenames	//	DiskInfo->NameBuffer = VdkAllocMem(name_total);	if (!DiskInfo->NameBuffer) {		VDKTRACE(VDKOPEN,			("[VDK] Can't allocate memory for image path\n"));		status = VDK_NOMEMORY;		goto cleanup_exit;	}	DiskInfo->BufferLen = name_total;	VdkCopyMem(DiskInfo->NameBuffer, name_top, name_total);cleanup_exit:	if (!VDKSUCCESS(status)) {		VdkCloseDisk(DiskInfo);	}	return status;}//// Prepare extra parameters for COWD//VDKSTAT VdkSetCowdParam(	PVDK_FILE_INFO	FileInfo,	ULONG			ReadOnly){	PVDK_COWD_PARAM	cowd_prm = NULL;	PCOWD_SECTOR_0	cowd_hdr = NULL;	VDKSTAT			status = VDK_OK;	//

⌨️ 快捷键说明

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