//=============================================================================
//
// Compuware Corporation
// NuMega Lab
// 9 Townsend West
// Nashua, NH 03060 USA
//
// Copyright (c) 1998 Compuware Corporation. All Rights Reserved.
// Unpublished - rights reserved under the Copyright laws of the
// United States.
//
//=============================================================================
// RFSDIOS.C - I/O Subsystem interface for Registry File System
// Copyright (c) 1996, Compuware Corporation
// This module contains functions that are called by the IOS.
#include "ramdisk.h"
#include PAGEABLE_CODE_SEGMENT
#include PAGEABLE_DATA_SEGMENT
//BYTE Drive;
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// 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(IOP* 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(IOP* 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
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Function
// RAMDISK_Aer
//
// Purpose
// Async Event Routine for RFSD
//
// Parameters
// pAep pointer to the AEP structure
//
// Return Value
// Depends on AEP subfunction.
//
// Remarks
// The function name is required by usage of the macro
// Define_Port_Driver (see regfsd.c).
//
// We handle the following AEPs:
//
// AEP_INITIALIZE: create a DDB for our virtual drive
// AEP_INQUIRY: set up a fake DCB
// AEP_CONFIG_DCB: associate drive letter and insert into
// calldown list
// AEP_BOOT_COMPLETE: signal OK
//
VOID OnRequest(IOP* iop);
int ndevices = 0; // # devices we've found
VOID __cdecl RAMDISK_Aer(AEP* pAep)
{
DCB* pDcb;
IOSDDB* pNewDDB;
ISP_ddb_create CreateDDBPacket;
ISP_calldown_insert InsertISP;
switch (pAep->AEP_func)
{
case AEP_INITIALIZE:
// Create a DDB for our "controller". This will cause IOS to send
// AEP_INQUIRY packets for each unit on the controller.
CreateDDBPacket.ISP_ddb_hdr.ISP_func = ISP_CREATE_DDB;
CreateDDBPacket.ISP_ddb_hdr.ISP_result = 0;
CreateDDBPacket.ISP_ddb_size = sizeof(IOSDDB);
CreateDDBPacket.ISP_ddb_ptr = 0;
CreateDDBPacket.ISP_ddb_flags = 0;
RAMDISK_Ilb.ILB_service_rtn((PISP)&CreateDDBPacket);
pNewDDB = (IOSDDB*)CreateDDBPacket.ISP_ddb_ptr;
pAep->AEP_result = AEP_SUCCESS;
break;
case AEP_UNINITIALIZE:
pAep->AEP_result = AEP_SUCCESS;
break;
case AEP_DEVICE_INQUIRY:
// The IOS sends this in response to the creation of the DDB. On the
// first call (DCB_unit_on_ctl == 0) we set up the supplied fake DCB
// with the parametes for our virtual drive. On subsequent calls, we
// anwer "no more devices". This terminates the inquiry.
pDcb = (DCB*)(((AEP_inquiry_device*)pAep)->AEP_i_d_dcb);
ASSERT(pDcb);
if (pDcb->DCB_unit_on_ctl == 0)
{
strcpy(pDcb->DCB_vendor_id, "ZXYZLL");
strcpy(pDcb->DCB_product_id, "VRAMDISK");
strcpy(pDcb->DCB_port_name, "VRAMDISK");
pAep->AEP_result = AEP_SUCCESS;
}
else
pAep->AEP_result = AEP_NO_MORE_DEVICES;
break;
case AEP_CONFIG_DCB:
// The IOS sends this AEP after each successful inquiry call. We
// associate the DCB with a drive letter and insert the request
// handler into the calldown chain.
pDcb = (DCB*)(((AEP_dcb_config*)pAep)->AEP_d_c_dcb);
ASSERT(pDcb);
if (!(pDcb->DCB_cmn.DCB_device_flags & DCB_DEV_PHYSICAL))
{
pAep->AEP_result = AEP_SUCCESS;
break;
}
ASSERT(memcmp(pDcb->DCB_vendor_id, "ZXYZLL", 6) == 0);
SetupDCB(pDcb);
//Drive = AssociateDriveLetter((DCB_COMMON*)pDcb);
memset(&InsertISP, 0, sizeof(InsertISP));
InsertISP.ISP_i_cd_hdr.ISP_func = ISP_INSERT_CALLDOWN;
InsertISP.ISP_i_cd_hdr.ISP_result = 0;
InsertISP.ISP_i_cd_dcb = (DCB_COMMON *)pDcb;
InsertISP.ISP_i_cd_req = OnRequest;
InsertISP.ISP_i_cd_ddb = (PDDB) (((AEP_dcb_config*)pAep)->AEP_d_c_hdr.AEP_ddb);
InsertISP.ISP_i_cd_expan_len = 0;
InsertISP.ISP_i_cd_flags = pDcb->DCB_cmn.DCB_dmd_flags | DCB_dmd_serialize;
InsertISP.ISP_i_cd_lgn = ((AEP_dcb_config*)pAep)->AEP_d_c_hdr.AEP_lgn;
RAMDISK_Ilb.ILB_service_rtn((PISP)&InsertISP);
++ndevices; // this will cause us to stay loader after next AEP_BOOT_COMPLETE
pAep->AEP_result = AEP_SUCCESS;
break;
case AEP_UNCONFIG_DCB:
pDcb = (DCB*)(((PAEP_dcb_unconfig)pAep)->AEP_d_u_dcb);
ASSERT(pDcb);
if (!(pDcb->DCB_cmn.DCB_device_flags & DCB_DEV_PHYSICAL)
|| memcmp(pDcb->DCB_vendor_id, "ZXYZLL", 6) != 0)
{
pAep->AEP_result = AEP_SUCCESS;
break;
}
--ndevices; // this will cause to unload after next AEP_BOOT_COMPLETE
ASSERT(ndevices >= 0);
pAep->AEP_result = AEP_SUCCESS;
break;
case AEP_BOOT_COMPLETE:
pAep->AEP_result = ndevices ? AEP_SUCCESS : AEP_FAILURE; // unload if no devices
break;
default:
pAep->AEP_result = AEP_FAILURE;
break;
}
}
VOID OnRequest(IOP* 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) (base + 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) (base + 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
RAM disk
需积分: 0 88 浏览量
2008-03-27
20:33:20
上传
评论
收藏 12KB RAR 举报
hzq701
- 粉丝: 1
- 资源: 7
最新资源
- 重启进行BIOS快捷方式,不需要开机按BIOS键
- 威纶通触摸屏编程软件Easy builder pro V6.09.01.556安装包(2024.04).txt
- WindowsAdminCenter
- 老飞飞搭建基础通用数据库V19数据库.rar
- jquery.js
- 机械设计多工位ACF贴胶带&预压设备sw18可编辑非常好的设计图纸100%好用.zip
- 基于Pytorch复现Point-Transformer,用于ShapeNet数据集点云分割
- 【医学影像分析】2D超声图像的分割检测(Ultrasound Nerve Segmentation - Kaggle数据集)
- 嘎嘎香的五款神仙谷歌插件
- .arch书源导入教程.mp4
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
评论0