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

📄 ramdisk.c

📁 一个内存驱动器的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	bsp->secsize = 512;					// each sector is 512 bytes long
	bsp->clustsize = 1;					// one sector per cluster
	bsp->numrsv = 1;					// no reserved sectors besides this one
	bsp->numfat = 1;					// one FAT should be enough
	bsp->numfiles = 128;				// more than enough to prove the point!
	bsp->numsectors = 0;				// fill in totsectors instead
	bsp->media = 0xF8;					// claim we're a fixed disk
	bsp->fatsectors = (WORD) ((nsec + nsec + 511) / 512);
	bsp->tracksectors = (WORD) nsec;	// only 1 track, so all sectors are on it
	bsp->numtracks = 1;					// 1 track
	bsp->numhidden = 0;					// no hidden sectors
	bsp->totsectors = nsec;				// this many sectors
	bsp->drive = 0x80;					// flag for a hard drive
	bsp->xboot = 0x29;					// flag as extended boot sector
	bsp->volid = base;					// use base address as volume ID
	memcpy(bsp->label, "NO NAME    ", 11);
	memcpy(bsp->fattype, "FAT16   ", 8);
	
	bsp->part[0].indicator = 0x80;
	bsp->part[0].parttype = 4;			// DOS 16-bit FAT
	bsp->part[0].bias = 0;
	bsp->part[0].partsize = nsec;
	
	bsp->signature = 0xAA55;					// boot sector signature

	// Initialize the start of the FAT at sector 1

	fat[0] = 0xFFF8;			// reserved bytes
	fat[1] = 0xFFFF;
	}							// InitRamDisk

///////////////////////////////////////////////////////////////////////////////
// AEP_UNCONFIG_DCB informs us that the physical device represented by a DCB
// is going away

#pragma VxD_PAGEABLE_CODE_SEG

USHORT OnUnconfigDcb(PAEP_dcb_unconfig aep)
	{							// OnUnconfigDcb
	PDCB dcb = (PDCB) aep->AEP_d_u_dcb;
	ASSERT(dcb);

	// We will get UNCONFIG calls for logical DCBs that are associated
	// with the physical device. We need to ignore these calls! We will
	// also occasionally get calls for DCBs that have nothing to do with
	// us at all (?)

	if (!(dcb->DCB_cmn.DCB_device_flags & DCB_DEV_PHYSICAL)
		|| memcmp(dcb->DCB_vendor_id, "WALTONEY", 8) != 0)
		return AEP_SUCCESS;		// ignore unconfig of logical DCB

	if (dcb->DCB_Port_Specific)
		{						// release memory
		_PageFree((PVOID) dcb->DCB_Port_Specific, 0);
		dcb->DCB_Port_Specific = 0;
		}						// release memory
	--ndevices;					// this will cause to unload after next AEP_BOOT_COMPLETE
	ASSERT(ndevices >= 0);
	return AEP_SUCCESS;
	}							// OnUnconfigDcb

///////////////////////////////////////////////////////////////////////////////
// AEP_DEVICE_INQUIRY asks us whether there's a physical device at a given
// controller-relative index. In this sample, we support one device per
// controller. A real device would examine BIOS entries or use some hardware-
// oriented method to enumerate the devices

#pragma VxD_PAGEABLE_CODE_SEG

USHORT OnDeviceInquiry(PAEP_inquiry_device aep)
	{							// OnDeviceInquiry
	PDCB dcb = (PDCB) aep->AEP_i_d_dcb;
	ASSERT(dcb);
	if (dcb->DCB_unit_on_ctl > 0)
		return AEP_NO_MORE_DEVICES;

	memcpy(dcb->DCB_vendor_id, "WALTONEY", 8);
	memcpy(dcb->DCB_product_id, "RAM Disk        ", 16);
	memcpy(dcb->DCB_rev_level, "0001", 4);
	
	return AEP_SUCCESS;
	}							// OnDeviceInquiry

///////////////////////////////////////////////////////////////////////////////
// AEP_UNINITIALIZE means the DDB is about to be deleted, meaning
// the controller is about to be removed.

#pragma VxD_PAGEABLE_CODE_SEG

USHORT OnUninitialize(PAEP_bi_uninit aep)
	{							// OnUninitialize
	return AEP_SUCCESS;
	}							// OnUninitialize

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// I/O request processing:

#pragma VxD_LOCKED_CODE_SEG

void DoCallDown(PIOP iop);
void DoCallBack(PIOP iop);

VOID OnRequest(PIOP iop)
	{							// OnRequest
	#define ior iop->IOP_ior
	DWORD funcode = ior.IOR_func;
	PDCB dcb = (PDCB) iop->IOP_physical_dcb;

	ior.IOR_status = IORS_SUCCESS; // assume it'll succeed
	dcb->DCB_cmn.DCB_device_flags |= DCB_DEV_IO_ACTIVE;

	switch (funcode)
		{					// dispatch function processor

	///////////////////////////////////////////////////////////////////////
	
	case IOR_READ:			// IOR_func == 0
		{					// IOR_READ
		DWORD sector = ior.IOR_start_addr[0];
		PBYTE diskdata = (PBYTE) (dcb->DCB_Port_Specific + sector * dcb->DCB_actual_blk_size);

		ASSERT(sector < dcb->DCB_actual_sector_cnt[0]);
		ASSERT(ior.IOR_start_addr[1] == 0);

		if (ior.IOR_flags & IORF_SCATTER_GATHER)
			{				// have scatter/gather structures
			_BlockDev_Scatter_Gather* sgd = (_BlockDev_Scatter_Gather*) ior.IOR_buffer_ptr;
			PBYTE memdata;
			DWORD nbytes;
			while ((nbytes = sgd->BD_SG_Count))
				{			// for each s/g structure
				memdata = (PBYTE) sgd->BD_SG_Buffer_Ptr; // linear address!
				if (!(ior.IOR_flags & IORF_CHAR_COMMAND))
					nbytes *= dcb->DCB_actual_blk_size;
				memcpy(memdata, diskdata, nbytes);
				diskdata += nbytes;
				++sgd;
				}			// for each s/g structure
			}				// have scatter/gather structures
		else
			{				// have simple buffer address
			PBYTE memdata = (PBYTE) ior.IOR_buffer_ptr;
			DWORD nbytes = ior.IOR_xfer_count;
			if (!(ior.IOR_flags & IORF_CHAR_COMMAND))
				nbytes *= dcb->DCB_actual_blk_size;
			memcpy(memdata, diskdata, nbytes);
			}				// have simple buffer address
		
		break;
		}					// IOR_READ

	///////////////////////////////////////////////////////////////////////
	
	case IOR_WRITE:			// IOR_func == 1
		{					// IOR_WRITE
		DWORD sector = ior.IOR_start_addr[0];
		PBYTE diskdata = (PBYTE) (dcb->DCB_Port_Specific + sector * dcb->DCB_actual_blk_size);

		ASSERT(sector);		// why is anyone rewriting the boot sector??
		ASSERT(sector < dcb->DCB_actual_sector_cnt[0]);
		ASSERT(ior.IOR_start_addr[1] == 0);

		if (ior.IOR_flags & IORF_SCATTER_GATHER)
			{				// have scatter/gather structures
			_BlockDev_Scatter_Gather* sgd = (_BlockDev_Scatter_Gather*) ior.IOR_buffer_ptr;
			PBYTE memdata;
			DWORD nbytes;
			while ((nbytes = sgd->BD_SG_Count))
				{			// for each s/g structure
				memdata = (PBYTE) sgd->BD_SG_Buffer_Ptr; // linear address!
				if (!(ior.IOR_flags & IORF_CHAR_COMMAND))
					nbytes *= dcb->DCB_actual_blk_size;
				memcpy(diskdata, memdata, nbytes);
				diskdata += nbytes;
				++sgd;
				}			// for each s/g structure
			}				// have scatter/gather structures
		else
			{				// have simple buffer address
			PBYTE memdata = (PBYTE) ior.IOR_buffer_ptr;
			DWORD nbytes = ior.IOR_xfer_count;
			if (!(ior.IOR_flags & IORF_CHAR_COMMAND))
				nbytes *= dcb->DCB_actual_blk_size;
			memcpy(diskdata, memdata, nbytes);
			}				// have simple buffer address
		
		break;
		}					// IOR_WRITE

	///////////////////////////////////////////////////////////////////////

	default:
		dcb->DCB_cmn.DCB_device_flags &= ~DCB_DEV_IO_ACTIVE;
		DoCallDown(iop);
		return;
		}					// dispatch function processor

	dcb->DCB_cmn.DCB_device_flags &= ~DCB_DEV_IO_ACTIVE;
	DoCallBack(iop);		// we're done with this request

	#undef ior
	}							// OnRequest

// DoCallDown passes a request to the next lower layer. Note that the
// documentation about how to do this is totally wrong: you don't just
// add sizeof(DCB_cd_entry) to the calldown pointer, you follow a
// linked list from one calldown entry to the next.

void __declspec(naked) DoCallDown(PIOP iop)
	{							// DoCallDown
	_asm
		{						// call down to next layer
		mov	ecx, [esp+4]
		mov	eax, [ecx]IOP.IOP_calldown_ptr
		mov eax, [eax]DCB_cd_entry.DCB_cd_next
		mov [ecx]IOP.IOP_calldown_ptr, eax
		jmp [eax]DCB_cd_entry.DCB_cd_io_address
		}						// call down to next layer
	}							// DoCallDown

// DoCallBack handles completion of an I/O request by calling the
// previous level's callback routine.

void __declspec(naked) DoCallBack(PIOP iop)
	{							// DoCallBack
	_asm
		{						// call back to previous layer
		mov ecx, [esp+4]
		sub [ecx]IOP.IOP_callback_ptr, size IOP_callback_entry
		mov eax, [ecx]IOP.IOP_callback_ptr
		jmp [eax]IOP_callback_entry.IOP_CB_address
		}						// call back to previous layer
	}							// DoCallBack

⌨️ 快捷键说明

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