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

📄 blkdev.c

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

#include "shared\vxddebug.h"
#include "shared\blkdev.h"

/*
 * This module implements the interface to blockdevices.
 * A device is represented by a TDevice object (which is
 * a DCB).
 */

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


/*********************************
 *
 * SECTOR BASED INTERFACE ROUNTINES
 *
 **********************************/

/*
 * Read one or more consecutive sectors from a blockdevice
 *
 * PRE CONDITIONS:
 * Device is a valid blockdevice. Data is large enough
 * to store the sector(s) in.
 * 
 * POST CONDITIONS:
 * If successfull, Data contains the read sector(s).
 *
 * IN:
 *	Device:		Valid reference to a block device
 *	StartSector:Starting sector on the block device
 *	NrSector:	Number of sectors to read
 *
 * OUT:
 *	Data:		Buffer to store the read sectors in
 *
 * RETURNS:
 * On success TRUE, FALSE otherwise
 *
 */
BOOL DevReadSectorObsolete(TDevice Device, ULONG StartSector, ULONG NrSectors, char *Data)
{
	USHORT	Rval;
	PDCB	Dcb		= (PDCB) Device;
	USHORT	Offset	= (USHORT) (Dcb->DCB_cmn.DCB_expansion_length + FIELDOFFSET(IOP, IOP_ior));
	USHORT	Size	= Offset + sizeof(IOR) + Dcb->DCB_max_sg_elements * sizeof(SGD);
	PIOP	Iop		= IspCreateIop(Size, Offset, ISP_M_FL_MUST_SUCCEED);
	PIOR	Ior		= &Iop->IOP_ior;

	VxdDebugPrint(D_BLKDEV, "DevReadSector: device=%x, sector=%lu, nr=%lu", ((ULONG) Device), StartSector, NrSectors);

	Iop->IOP_original_dcb = (struct _DCB_COMMON *) Dcb;
	Iop->IOP_physical_dcb = (struct _DCB_COMMON *) Dcb->DCB_cmn.DCB_physical_dcb;

	Ior->IOR_next = 0;					// used for request queueing by lots of downstream people
	Ior->IOR_start_addr[1] = 0;			// assume only 32-bits worth of sector number
	Ior->IOR_flags = IORF_VERSION_002;	// this is how IOS knows we're giving it a new-style IOR
	Ior->IOR_private_client = Offset;	// a common use for this field
	Ior->IOR_req_vol_handle = Dcb->DCB_cmn.DCB_vrp_ptr;
	Ior->IOR_sgd_lin_phys = (ULONG) (Ior + 1); // where scatter/gather descriptors can be built
	Ior->IOR_num_sgds = 0;				// incremented by criteria routine, so must start at zero
	Ior->IOR_vol_designtr = Dcb->DCB_cmn.DCB_unit_number;

	Ior->IOR_func = IOR_READ;			// flag as read request
	Ior->IOR_flags |= IORF_SYNC_COMMAND // don't return until complete
		| IORF_HIGH_PRIORITY			// used for adminstrative-type requests, but optional
		| IORF_BYPASS_VOLTRK;			// we want to bypass volume tracking and just read the MBR
	Ior->IOR_buffer_ptr = (ULONG) Data;	// buffer to read into

	Ior->IOR_start_addr[0] = StartSector;
	Ior->IOR_xfer_count = NrSectors;

	IlbIntIoCriteria(Iop);
	IlbInternalRequest(Iop, Dcb, NULL);

	Rval = Ior->IOR_status;

	IspDeallocMem((PVOID) ((DWORD) Ior - Ior->IOR_private_client));

	if (Rval)
	{
		VxdDebugPrint(D_BLKDEV, "DevReadSector: device=%x, sector=%lu, nr=%lu", ((ULONG) Device), StartSector, NrSectors);
		return FALSE;
	}

	VxdDebugPrint(D_BLKDEV, "DevReadSector: done, device=%x, sector=%lu, nr=%lu", ((ULONG) Device), StartSector, NrSectors);

	return TRUE;
}



/*
 * Read one or more consecutive sectors from a blockdevice
 *
 * PRE CONDITIONS:
 * Device is a valid blockdevice. Data is large enough
 * to store the sector(s) in.
 * 
 * POST CONDITIONS:
 * If successfull, Data contains the read sector(s).
 *
 * IN:
 *	Device:		Valid reference to a block device
 *	StartSector:Starting sector on the block device
 *	NrSector:	Number of sectors to read
 *
 * OUT:
 *	Data:		Buffer to store the read sectors in
 *
 * RETURNS:
 * On success TRUE, FALSE otherwise
 *
 */
BOOL DevReadSector(TDevice Device, ULONG StartSector, ULONG NrSectors, char *Data)
{
	USHORT	Rval;
	PDCB	Dcb		= (PDCB) Device;
	USHORT	Offset	= (USHORT) (Dcb->DCB_cmn.DCB_expansion_length + FIELDOFFSET(IOP, IOP_ior));
	USHORT	Size	= Offset + sizeof(IOR) + Dcb->DCB_max_sg_elements * sizeof(SGD);
	PIOP	Iop		= IspCreateIop(Size, Offset, ISP_M_FL_MUST_SUCCEED);
	PIOR	Ior		= &Iop->IOP_ior;

	VxdDebugPrint(D_BLKDEV, "DevReadSector: device=%x, sector=%lu, nr=%lu", ((ULONG) Device), StartSector, NrSectors);

	Iop->IOP_original_dcb = (struct _DCB_COMMON *) Dcb;
	Iop->IOP_physical_dcb = (struct _DCB_COMMON *) Dcb->DCB_cmn.DCB_physical_dcb;

	Ior->IOR_next = 0;					// used for request queueing by lots of downstream people
	Ior->IOR_start_addr[1] = 0;			// assume only 32-bits worth of sector number
	Ior->IOR_flags = IORF_VERSION_002;	// this is how IOS knows we're giving it a new-style IOR
	Ior->IOR_private_client = Offset;	// a common use for this field
	Ior->IOR_req_vol_handle = Dcb->DCB_cmn.DCB_vrp_ptr;
	Ior->IOR_sgd_lin_phys = (ULONG) (Ior + 1); // where scatter/gather descriptors can be built
	Ior->IOR_num_sgds = 0;				// incremented by criteria routine, so must start at zero
	Ior->IOR_vol_designtr = Dcb->DCB_cmn.DCB_unit_number;

	Ior->IOR_func = IOR_READ;			// flag as read request
	Ior->IOR_flags |= IORF_SYNC_COMMAND // don't return until complete
		| IORF_HIGH_PRIORITY			// used for adminstrative-type requests, but optional
		| IORF_BYPASS_VOLTRK;			// we want to bypass volume tracking and just read the MBR
	Ior->IOR_buffer_ptr = (ULONG) Data;	// buffer to read into

	Ior->IOR_start_addr[0] = StartSector;
	Ior->IOR_start_addr[1] = 0;
	Ior->IOR_xfer_count = NrSectors;
	if (Iop->IOP_original_dcb->DCB_device_flags & DCB_DEV_LOGICAL)
		Ior->IOR_flags |= IORF_LOGICAL_START_SECTOR;

	IlbIntIoCriteria(Iop);
	IlbInternalRequest(Iop, Dcb, NULL);

	Rval = Ior->IOR_status;

	IspDeallocMem((PVOID) ((DWORD) Ior - Ior->IOR_private_client));

	if (Rval)
	{
		VxdDebugPrint(D_BLKDEV, "DevReadSector: error, IOR_status=%lu", (ULONG) Rval);
		return FALSE;
	}

	VxdDebugPrint(D_BLKDEV, "DevReadSector: done");

	return TRUE;
}




/*********************************
 *
 * BLOCK BASED INTERFACE ROUNTINES
 *
 **********************************/

/*
 * Set the logical blocksize for a blockdevice
 *
 * PRE CONDITIONS:
 * Device is a valid blockdevice.
 *
 * POST CONDITIONS:
 * Device blocksize is set to 2 to the power LogBlockSize
 * 
 * IN:
 *	Device:			Valid reference to a block device
 *	LogBlockSize:	log of the block size (blocksize = 1 << log)
 *
 */
void DevSetLogBlockSize(TDevice Device, ULONG LogBlockSize)
{
	PDCB Dcb;

	Dcb = (PDCB) Device;

	Dcb->DCB_cmn.DCB_apparent_blk_shift = (UCHAR) LogBlockSize;

	VxdDebugPrint(D_BLKDEV, "DevSetLogBlockSize: log=%lu, size=%lu", LogBlockSize, (ULONG) (512 << LogBlockSize));
}


/*
 * Get the logical blocksize for a blockdevice
 *
 * PRE CONDITIONS:
 * Device is a valid blockdevice.
 *
 * POST CONDITIONS:
 * <none>
 * 
 * IN:
 *	Device:			Valid reference to a block device
 *
 * RETURNS:
 * The logical blocksize of the block device
 *
 */
USHORT DevGetLogBlockSize(TDevice Device)
{
	PDCB Dcb;

	Dcb = (PDCB) Device;

	return Dcb->DCB_cmn.DCB_apparent_blk_shift;
}

/*
 * Get the partition type of a blockdevice
 *
 * PRE CONDITIONS:
 * Device is a valid blockdevice.
 *
 * POST CONDITIONS:
 * <none>
 *
 * IN:
 *	Device:			Valid reference to a block device
 *
 * RETURNS:
 * The partition type
 *
 */
UCHAR DevGetPartitionType(TDevice Device)
{
	PDCB Dcb;

	Dcb = (PDCB) Device;

	VxdDebugPrint(D_BLKDEV, "DevGetPartitionType: device=%lu, type=0x%x", ((ULONG) Device), (ULONG) Dcb->DCB_cmn.DCB_partition_type);

	return Dcb->DCB_cmn.DCB_partition_type;
}



void DevGenerateName(TDevice Device, char *DevName)
{
	sprintf(DevName, "%s", "/dev/hdtest");
}



/*
 * Read a block from a blockdevice
 *
 * PRE CONDITIONS:
 * Device is a valid blockdevice. BlockData is large enough
 * to store the block in.
 * 
 * POST CONDITIONS:
 * If successfull, BlockData contains the read block.
 *
 * IN:
 *	Device:		Valid reference to a block device
 *	BlockNo:	Logical block number of the block to read
 *
 * OUT:
 *	BlockData:	Buffer to store the read block in
 *
 * RETURNS:
 * On success TRUE, FALSE otherwise
 *
 */
BOOL DevReadBlockObsolete(TDevice Device, ULONG BlockNo, UCHAR *BlockData)
{
	BOOL	Succes;
	PDCB	Dcb;
	PDCB	DcbPhysical;
	ULONG	StartSector;
	ULONG	NrSectors;

	VxdDebugPrint(D_BLKDEV, "DevReadBlock: device=%x, blockno=%lu", (ULONG) Device, BlockNo);

	Dcb = (PDCB) Device;
	DcbPhysical = (PDCB) ((PDCB_COMMON) Dcb)->DCB_physical_dcb;

	StartSector = (BlockNo << Dcb->DCB_cmn.DCB_apparent_blk_shift);
	NrSectors = (1 << Dcb->DCB_cmn.DCB_apparent_blk_shift);

		/*
		 * Account for the fact we read from the physical disk directly
		 */
	StartSector += Dcb->DCB_cmn.DCB_Partition_Start;

//	Succes = DevReadSector(DcbPhysical, StartSectorHigh, StartSectorLow, NrSectors, BlockData);
	if (!Succes)
		VxdDebugPrint(D_ERROR, "DevReadBlock: device=%x, blockno=%lu", (ULONG) Device, BlockNo);
	else		
		VxdDebugPrint(D_BLKDEV, "DevReadBlock: done, device=%x, blockno=%lu", (ULONG) Device, BlockNo);

	return Succes;	
}





/*
 * Read a block from a blockdevice
 *
 * PRE CONDITIONS:
 * Device is a valid blockdevice. BlockData is large enough
 * to store the block in.
 * 
 * POST CONDITIONS:
 * If successfull, BlockData contains the read block.
 *
 * IN:
 *	Device:		Valid reference to a block device
 *	BlockNo:	Logical block number of the block to read
 *
 * OUT:
 *	BlockData:	Buffer to store the read block in
 *
 * RETURNS:
 * On success TRUE, FALSE otherwise
 *
 */
BOOL DevReadBlock(TDevice Device, ULONG BlockNo, UCHAR *BlockData)
{
	BOOL	Succes;
	PDCB	Dcb;
	PDCB	DcbPhysical;
	ULONG	StartSector;
	ULONG	NrSectors;

	VxdDebugPrint(D_BLKDEV, "DevReadBlock: device=%x, blockno=%lu", (ULONG) Device, BlockNo);

	Dcb = (PDCB) Device;
	DcbPhysical = (PDCB) ((PDCB_COMMON) Dcb)->DCB_physical_dcb;

	StartSector = (BlockNo << Dcb->DCB_cmn.DCB_apparent_blk_shift);
	NrSectors = (1 << Dcb->DCB_cmn.DCB_apparent_blk_shift);

		/*
		 * Account for the fact we read from the physical disk directly
		 */
	StartSector += Dcb->DCB_cmn.DCB_Partition_Start;

	Succes = DevReadSector(DcbPhysical,  StartSector, NrSectors, BlockData);
	if (!Succes)
		VxdDebugPrint(D_ERROR, "DevReadBlock: device=%x, blockno=%lu", (ULONG) Device, BlockNo);
	else		
		VxdDebugPrint(D_BLKDEV, "DevReadBlock: done, device=%x, blockno=%lu", (ULONG) Device, BlockNo);

	return Succes;	
}



⌨️ 快捷键说明

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