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

📄 parttbl.c

📁 Win9x下文件系统驱动的例子(EXT2)源代码。
💻 C
字号:
#include "vxd.h"

#include "shared\partwalk.h"
#include "shared\vxddebug.h"
#include "shared\blkdev.h"
#include "shared\fsdioctl.h"
#include "parttbl.h"
#include "Dcb.h"



/**********************************
 *
 * STATIC DATA
 *
 **********************************/


static TPartitionTableEntry		sPartitionTable[PART_TABLE_ENRTIES];


/*********************************
 *
 * STATIC HELPERS
 *
 **********************************/


void PrintPartitionTable()
{
	int						Disk, PartitionNo;
	TPartitionTableEntry	*Partition;


	VxdDebugPrint(D_PARTITION, "****** PARTITION TABLE ******");

	for (Disk=0 ; Disk < MAX_IDE_DISK + MAX_SCSI_DISK ; Disk++)
	{
		for (PartitionNo=0 ; PartitionNo<MAX_PARTITION_PER_DISK ; PartitionNo++)
		{
			Partition = &sPartitionTable[Disk*MAX_PARTITION_PER_DISK + PartitionNo];
			if (Partition->nrSectors && Partition->StartSector)
			{
				VxdDebugPrint(D_PARTITION, "/dev/%s%c%i, %4lu MB, type=%xh   %s",
					Disk < MAX_IDE_DISK ? "hd" : "sd",
					Disk < MAX_IDE_DISK ? Disk + 'a' : Disk-MAX_IDE_DISK + 'a',
					PartitionNo,
					(ULONG) Partition->nrSectors >> 11,
					(int) Partition->PartitionType,
					(!(Partition->Dcb) && Partition->PartitionType == TYPE_LINUX_PARTITION) ? "(not recognised by fsdext2)" : ""
					);
			}
		}
	}

	VxdDebugPrint(D_PARTITION, "****** PARTITION TABLE ******");
}



/*
 * Given a partitionentry, we scan the physical DCB for a logical
 * dcb that matches the partition
 */
static void SearchForDcb(PDCB PhysicalDcb, TPartitionTableEntry *Entry)
{
	PDCB_COMMON	Dcb = ((PDCB_COMMON) PhysicalDcb)->DCB_next_logical_dcb;

	VxdDebugPrint(D_PARTITION, "SearchForDcb: start");

	while (Dcb)
	{
		if (Dcb->DCB_Partition_Start == Entry->StartSector 
				&& Dcb->DCB_partition_type == Entry->PartitionType)
		{
			VxdDebugPrint(D_PARTITION, "SearchForDcb: done, found DCB");
			Entry->Dcb = Dcb;
			return;
		}

		Dcb = Dcb->DCB_next_logical_dcb;
	}
	VxdDebugPrint(D_PARTITION, "SearchForDcb: done, nothing found");
}




/*
 * This is the callback passed to WalkPartitions. It is called for
 * each partition found on the specified disk.
 * We fill in the corresponding entry in the partition table and
 * scan for a logical DCB that correpsonds the partition entry found
 */
static void HandlePartition(PDCB Dcb, int Disk, TDiskPartition *DiskPartition, int PartitionNo)
{
 	TPartitionTableEntry	*Entry;

	Entry = &sPartitionTable[Disk * MAX_PARTITION_PER_DISK + PartitionNo];

	Entry->PartitionType = DiskPartition->sys_ind;
	Entry->nrSectors = DiskPartition->nr_sec;
	Entry->StartSector = DiskPartition->start_sec;

	VxdDebugPrint(D_PARTITION, "HandlePartition: %s%c%i, %4lu MB, type=%i",
		Disk < MAX_IDE_DISK ? "hd" : "sd",
		Disk < MAX_IDE_DISK ? Disk + 'a' : Disk-MAX_IDE_DISK + 'a',
		PartitionNo,
		(ULONG) DiskPartition->nr_sec >> 11,
		(int) DiskPartition->sys_ind);

	SearchForDcb(Dcb, Entry);
}



/*********************************
 *
 * INTERFACE ROUNTINES
 *
 **********************************/

void PartitionGetTable(char **Table, DWORD *Size)
{
	*Table = (char *) sPartitionTable;
	*Size = sizeof(sPartitionTable);
}


BOOL PartitionMount(int Disk, int PartitionNo, int Drive, ULONG *Reply)
{
 	TPartitionTableEntry	*Entry;


	VxdDebugPrint(D_PARTITION, "PartitionMount: Disk=%i, PartitionNo=%i, Drive=%c",
			Disk, PartitionNo, Drive+'A');

	*Reply = 0;


	if (Disk > MAX_IDE_DISK + MAX_SCSI_DISK ||
			PartitionNo > MAX_PARTITION_PER_DISK ||
			Drive > 26)
	{
		VxdDebugPrint(D_PARTITION, "PartitionMount: done, invalid parameter");
		return FALSE;
	}

	Entry = &sPartitionTable[Disk * MAX_PARTITION_PER_DISK + PartitionNo];
	if (Entry->PartitionType != TYPE_LINUX_PARTITION)
	{
		VxdDebugPrint(D_PARTITION, "PartitionMount: done, not a linux partition");
		*Reply = ERROR_MOUNT_DEVICE_NOT_LINUX;
		return TRUE;
	} 

	if (Entry->Drive)
	{
		VxdDebugPrint(D_PARTITION, "PartitionMount: done, partition already mounted");
		*Reply = ERROR_MOUNT_DEVICE_ALREADY_MOUNTED;
		return TRUE;
	}

	if (!IspAssociateDcb((PDCB) Entry->Dcb, (CHAR) Drive, ISP_D_A_FL_NOSHELLMSG))
	{
		VxdDebugPrint(D_PARTITION, "PartitionMount: done, drive already exists");
		*Reply = ERROR_MOUNT_DRIVE_ALREADY_EXISTS;
		return TRUE;
	}
	VxdDebugPrint(D_PARTITION, "PartitionMount: done");

	return TRUE;
}



BOOL PartitionUMount(int Drive)
{
	return FALSE;
}





void PartitionInitialise()
{
	int				nrIde, nrScsi;
	PDCB_COMMON		Dcb;

	VxdDebugPrint(D_PARTITION, "PartitionInitialise: walking partition tables");

	nrIde = nrScsi = 0;
	Dcb = (PDCB_COMMON) IspGetFirstNextDcb(0, DCB_type_disk);
	memset(sPartitionTable, 0, sizeof(sPartitionTable));

	if (!Dcb)
	{
		VxdDebugPrint(D_PARTITION, "PartitionInitialise: no DCB found");
		return;
	}

	while(Dcb)
	{
		if (Dcb->DCB_device_flags & DCB_DEV_PHYSICAL)
		{
			if (((PDCB) Dcb)->DCB_bus_type == DCB_BUS_SCSI)
				WalkPartitions((PDCB) Dcb, MAX_IDE_DISK + nrScsi++, HandlePartition);
			else if (((PDCB) Dcb)->DCB_bus_type == DCB_BUS_ESDI)
				WalkPartitions((PDCB) Dcb, nrIde++, HandlePartition);
		}
		Dcb = (PDCB_COMMON) IspGetFirstNextDcb((PDCB) Dcb, DCB_type_disk);
	}
	VxdDebugPrint(D_PARTITION, "PartitionInitialise: done, nrIde=%i, nrScsi=%i", nrIde, nrScsi);

	PrintPartitionTable();
}


void PartitionGetDevice(void *Dcb, int *Disk, int *Partition)
{
	int						i;
 	TPartitionTableEntry	*Entry;
	
	*Disk = 0;
	*Partition = 0;

	for (i=0, Entry=sPartitionTable ; i<PART_TABLE_ENRTIES ; i++, Entry++)
	{
		if (Entry->Dcb == Dcb)
		{
			*Disk =i / MAX_PARTITION_PER_DISK;
			*Partition =i % MAX_PARTITION_PER_DISK;
		}
	}
}


⌨️ 快捷键说明

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