一个所谓的Ramdisk

来源:互联网 发布:python google翻译 编辑:程序博客网 时间:2024/05/16 07:17
当初学习《寒江独钓》时,被书中WDF结构的源码给吓着!磁盘虚拟好复杂。
经过二个星期的磁盘驱动学习,终于发现,其实Ramdisk可以更简单的,当然我说的不是基于wdf。
//**************************************************************************************
//    日期:    2010 /08 /21
//    创建:    ejoyc  
//    描述:   precomp.h: precompile header file
//**************************************************************************************
#pragma once

#include <ntifs.h>
#include <srb.h>
#include <ntddscsi.h>
#include <ntdddisk.h>
#include <scsi.h>
#include <Ntstrsafe.h>

#define MINIPORT_TIMER_PERIOD 100000

// MemDisk Device extension
typedef struct __tagMemDisk
{
ULONG                                m_ulBlockShift;            // block size
ULONG                                m_ulBlockCount;            // block count
PUCHAR                                m_lpMemDisk;            // MemDisk's memery address
}MEMDISK,*PMEMDISK;
// MemDisk SRB extension
typedef struct __tagSRBEXT
{
LIST_ENTRY                            m_ltEntry;    // linked list entry    
PSCSI_REQUEST_BLOCK                    m_pSrb;        // for nomal scsi request    
PMEMDISK                            m_pMemDisk;    // for mount image            
}SRBEXT,*PSRBEXT;

NTSTATUS    DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath);
VOID        DriverUnload(IN PDRIVER_OBJECT DriverObject);
BOOLEAN        MemDiskInitialize(PVOID DeviceExtension);
BOOLEAN        MemDiskStartIo(PVOID DeviceExtension,PSCSI_REQUEST_BLOCK pSrb);
ULONG        MemDiskFindAdapter(PVOID DeviceExtension,PVOID pHwContext,PVOID pBusInformation,PCHAR pArgumentString,PPORT_CONFIGURATION_INFORMATION pConfigInfo,PBOOLEAN pAgain);
BOOLEAN        MemDiskResetBus(PVOID DeviceExtensionension,ULONG ulPathId);
BOOLEAN        MemDiskAdapterState(PVOID DeviceExtension,PVOID pContext,BOOLEAN bSaveState);
SCSI_ADAPTER_CONTROL_STATUS MemDiskAdapterControl(PVOID DeviceExtension,SCSI_ADAPTER_CONTROL_TYPE ControlType,PVOID pParameters);
VOID        MemDiskCheckFinishTimer(PVOID DeviceExtension);
BOOLEAN        DoCheckFinish(PVOID DeviceExtension);
VOID        MemDiskProcSRBWorker(PVOID pContext);
BOOLEAN        ProcessSrb(PMEMDISK pExt,PSCSI_REQUEST_BLOCK pSrb);
NTSTATUS    MountMemDisk(PMEMDISK pExt);
NTSTATUS    LoadOrSaveData(PMEMDISK pExt,BOOLEAN bIsSaveData);

extern KEVENT                                g_NewSRBEvent;
extern KEVENT                                g_ShutdwonEvent;
extern KEVENT                                g_ThreadExitEvent;
extern LIST_ENTRY                            g_ltProcSRBHead;
extern KSPIN_LOCK                            g_ltProcSRBLook;
extern LIST_ENTRY                            g_ltFinishSRBHead;
extern KSPIN_LOCK                            g_ltFinishSRBLock;
extern BOOLEAN                                g_ExitFlag;
//**************************************************************************************
//    日期:    2010 /08 /21
//    创建:    ejoyc    
//    描述:   MemDiskEx.h: MemDisk driver entry
//**************************************************************************************

#include "precomp.h"

KEVENT                                g_NewSRBEvent;
KEVENT                                g_ShutdwonEvent;
KEVENT                                g_ThreadExitEvent;
LIST_ENTRY                            g_ltProcSRBHead;
KSPIN_LOCK                            g_ltProcSRBLook;
LIST_ENTRY                            g_ltFinishSRBHead;
KSPIN_LOCK                            g_ltFinishSRBLock;
BOOLEAN                                g_ExitFlag;

PDRIVER_UNLOAD OldDriverUnload=NULL;

NTSTATUS    DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)
{
NTSTATUS                Status;
HW_INITIALIZATION_DATA    hwInitData    = {0};
RtlZeroMemory(&hwInitData,sizeof(HW_INITIALIZATION_DATA));

hwInitData.HwInitializationDataSize = sizeof(HW_INITIALIZATION_DATA);// sizeof this struct
hwInitData.AdapterInterfaceType        = Isa;//Specifiy the bus type. 
hwInitData.HwFindAdapter            = MemDiskFindAdapter;// find adapter
hwInitData.HwInitialize                = MemDiskInitialize;// initialize
hwInitData.HwAdapterControl            = MemDiskAdapterControl;// adapter control    
hwInitData.HwAdapterState            = MemDiskAdapterState;// adapter state        
hwInitData.HwResetBus                = MemDiskResetBus;// reset bus    
hwInitData.HwStartIo                = MemDiskStartIo;// start io    

hwInitData.SrbExtensionSize            = sizeof(SRBEXT);
hwInitData.DeviceExtensionSize        = sizeof(MEMDISK);// device extension
hwInitData.NumberOfAccessRanges     = 0;
hwInitData.SpecificLuExtensionSize     = 0;

hwInitData.AutoRequestSense            = TRUE;// auto request sense    
hwInitData.MapBuffers                = TRUE;// need virtual address
hwInitData.MultipleRequestPerLu        = FALSE;// no multi request    
hwInitData.NeedPhysicalAddresses    = FALSE;// Indicate no buffer mapping but will need physical addresses.      
hwInitData.ReceiveEvent                = FALSE;        
hwInitData.TaggedQueuing            = FALSE;// do no support tagged queuing

// initialize event or lock
KeInitializeEvent(&g_ShutdwonEvent,NotificationEvent,FALSE);
KeInitializeEvent(&g_ThreadExitEvent,NotificationEvent,FALSE);

KeInitializeEvent(&g_NewSRBEvent,SynchronizationEvent,FALSE);
InitializeListHead(&g_ltProcSRBHead);
KeInitializeSpinLock(&g_ltProcSRBLook);

InitializeListHead(&g_ltFinishSRBHead);
KeInitializeSpinLock(&g_ltFinishSRBLock);

g_ExitFlag=FALSE;

KdPrint(("[MemDisk] *******DriverEntry...call ScsiPortInitialize\n"));
Status = ScsiPortInitialize(DriverObject,RegistryPath,&hwInitData,NULL);

OldDriverUnload = DriverObject->DriverUnload;
DriverObject->DriverUnload = DriverUnload;

return Status;
}

// driver unload
VOID DriverUnload(IN PDRIVER_OBJECT DriverObject)
{
if(OldDriverUnload)
{
KdPrint(("[MemDisk] *******DriverUnload...call ScsiportUnload.\n"));
OldDriverUnload(DriverObject);
}

KdPrint(("[MemDisk] *******DriverUnload...set shut down event\n"));

KeSetEvent(&g_ShutdwonEvent,IO_NO_INCREMENT,FALSE);
KeWaitForSingleObject(&g_ThreadExitEvent,Executive,KernelMode,FALSE,NULL);

g_ExitFlag=TRUE;

KdPrint(("[MemDisk] *******DriverUnload...the work thread terminated.then driver image can be safe unload.\n"));
}

// miniport adapter state
BOOLEAN MemDiskAdapterState(PVOID DeviceExtension,PVOID pContext,BOOLEAN bSaveState)
{
KdPrint(("[MemDisk] *******MemDiskAdapterState...just return TRUE\n"));
return TRUE;
}

// miniport initialize
BOOLEAN MemDiskInitialize(PVOID DeviceExtension)
{
NTSTATUS    Status;
HANDLE        hWorkerThread;
// create system thread
KdPrint(("[MemDisk] *******DriverEntry...create system thread\n"));
Status = PsCreateSystemThread( &hWorkerThread,THREAD_ALL_ACCESS,NULL,NULL,NULL,MemDiskProcSRBWorker,DeviceExtension);
if(Status==STATUS_SUCCESS)
{
KdPrint(("[MemDisk] *******MemDiskInitialize...work thread finished successfully,then set timer,and return true.\n"));
ScsiPortNotification(RequestTimerCall,DeviceExtension,MemDiskCheckFinishTimer,MINIPORT_TIMER_PERIOD);
return TRUE;
}

KeSetEvent(&g_ThreadExitEvent,IO_NO_INCREMENT,FALSE);
return FALSE;
}

// start io
BOOLEAN MemDiskStartIo(PVOID DeviceExtension,PSCSI_REQUEST_BLOCK pSrb)
{
PSRBEXT pSrbExt = (PSRBEXT)pSrb->SrbExtension;

pSrbExt->m_pSrb = pSrb;
pSrbExt->m_pMemDisk=(PMEMDISK)DeviceExtension;

switch(pSrb->Function) 
{
case SRB_FUNCTION_SHUTDOWN:
case SRB_FUNCTION_FLUSH:        
case SRB_FUNCTION_EXECUTE_SCSI:
case SRB_FUNCTION_IO_CONTROL:
pSrb->SrbStatus = SRB_STATUS_PENDING;
ExInterlockedInsertTailList(&g_ltProcSRBHead,&pSrbExt->m_ltEntry,&g_ltProcSRBLook);
KeSetEvent(&g_NewSRBEvent,IO_NO_INCREMENT,FALSE);
break;

default:
pSrb->SrbStatus = SRB_STATUS_BAD_FUNCTION;
ExInterlockedInsertTailList(&g_ltFinishSRBHead,&pSrbExt->m_ltEntry,&g_ltFinishSRBLock);
}    

DoCheckFinish(DeviceExtension);
return TRUE;
}

// find adapter
ULONG MemDiskFindAdapter(PVOID DeviceExtension,PVOID pHwContext,PVOID pBusInformation,PCHAR pArgumentString,PPORT_CONFIGURATION_INFORMATION pConfigInfo,PBOOLEAN pAgain)
{
*pAgain = FALSE;
pConfigInfo->AdapterInterfaceType    = PCIBus;
pConfigInfo->AlignmentMask            = 0x00000003;
pConfigInfo->AutoRequestSense        = TRUE;
pConfigInfo->BufferAccessScsiPortControlled = FALSE;
pConfigInfo->BusInterruptLevel        = 0;
pConfigInfo->BusInterruptVector        = 0;
pConfigInfo->Dma32BitAddresses        = TRUE;
pConfigInfo->Master                    = TRUE;
pConfigInfo->CachesData                = TRUE;
pConfigInfo->NumberOfBuses            = 1;
pConfigInfo->MaximumNumberOfTargets = 1;
pConfigInfo->MaximumTransferLength    = 0x10000;
pConfigInfo->MultipleRequestPerLu    = FALSE;
pConfigInfo->NumberOfPhysicalBreaks = 0x00F8;
pConfigInfo->ScatterGather            = TRUE;
pConfigInfo->TaggedQueuing            = FALSE;

KdPrint(("[MemDisk] *******MemDiskFindAdapter...found an adapter\n"));
return SP_RETURN_FOUND;
}

// reset bus
BOOLEAN MemDiskResetBus(PVOID DeviceExtensionension,ULONG ulPathId)
{
return TRUE;
}

// miniport adapter control
SCSI_ADAPTER_CONTROL_STATUS MemDiskAdapterControl(PVOID DeviceExtension,SCSI_ADAPTER_CONTROL_TYPE ctlType,PVOID pParameters)
{
PSCSI_SUPPORTED_CONTROL_TYPE_LIST     pList=NULL;
SCSI_ADAPTER_CONTROL_STATUS         status = ScsiAdapterControlSuccess;

switch(ctlType)
{
case ScsiQuerySupportedControlTypes:
pList = (PSCSI_SUPPORTED_CONTROL_TYPE_LIST)pParameters;
pList->SupportedTypeList[ScsiStopAdapter] = TRUE;
pList->SupportedTypeList[ScsiRestartAdapter] = TRUE;
pList->SupportedTypeList[ScsiQuerySupportedControlTypes] = TRUE;
KdPrint(("[MemDisk] *******MemDiskAdapterControl...ScsiQuerySupportedControlTypes(stop,restart,query)\n"));
break;

case ScsiStopAdapter:
KdPrint(("[MemDisk] *******MemDiskAdapterControl...ScsiStopAdapter,do nothing\n"));
break;

case ScsiRestartAdapter:
KdPrint(("[MemDisk] *******MemDiskAdapterControl...ScsiRestartAdapter,must set timer\n"));
ScsiPortNotification(RequestTimerCall,DeviceExtension,MemDiskCheckFinishTimer,MINIPORT_TIMER_PERIOD);
break;

default:
status = ScsiAdapterControlUnsuccessful;
break;
}

return status;
}

// check finish timer
// the completion of the miniport' SRB have 3 ways:in the HwScsiStartIo  or HwScsiInterrupt routine,or in  a routine which is specific 
// in ScsiPortNotification (NotificationType = RequestTimerCall)
VOID MemDiskCheckFinishTimer(PVOID DeviceExtension)
{
if(DoCheckFinish(DeviceExtension))
{
ScsiPortNotification(RequestTimerCall,DeviceExtension,MemDiskCheckFinishTimer,MINIPORT_TIMER_PERIOD);
}
else
{
KdPrint(("[MemDisk] *******MemDiskCheckFinishTimer...DoCheckFinish return false,do not request another timer call\n"));
}
}
//**************************************************************************************
//    日期:    2010 /08 /21
//    创建:    ejoyc        
//    描述:    Helper.c: MemDisk helper——处理MemDiskStartIo中发出的SRB;完成SRB;MemDisk初始化和保存数据
//**************************************************************************************
#include "precomp.h"

// check finish timer call
BOOLEAN DoCheckFinish(PVOID DeviceExtension)
{
PMEMDISK    pExt = (PMEMDISK)DeviceExtension;
PSRBEXT        pSrbExt=NULL;    

PLIST_ENTRY pltEntry = ExInterlockedRemoveHeadList(&g_ltFinishSRBHead,&g_ltFinishSRBLock);

while(pltEntry)
{
pSrbExt = CONTAINING_RECORD(pltEntry,SRBEXT,m_ltEntry);        

ScsiPortNotification(RequestComplete,DeviceExtension,pSrbExt->m_pSrb);//通知系统这个SRB已经处理完成
ScsiPortNotification(NextRequest,DeviceExtension,NULL);//通知系统,本驱动可以处理下一个SRB了

pltEntry = ExInterlockedRemoveHeadList(&g_ltFinishSRBHead,&g_ltFinishSRBLock);
}
return !g_ExitFlag;
}

// worker thread function
VOID MemDiskProcSRBWorker(PVOID pContext)
{
PLIST_ENTRY            pltEntry=NULL;
PSCSI_REQUEST_BLOCK pSrb=NULL;
PSRBEXT                pSrbExt =NULL;
PMEMDISK            pExt = NULL;
NTSTATUS            Status;
PVOID                pEvetObject[2] = {&g_NewSRBEvent,&g_ShutdwonEvent};    
BOOLEAN                bBreak = FALSE;

// set priority
KeSetPriorityThread(KeGetCurrentThread(),LOW_REALTIME_PRIORITY);    

if(MountMemDisk((PMEMDISK)pContext)==STATUS_SUCCESS)//Mount the MemDisk
{
for(;;)
{    // wait any one of the 2 events to become signaled
Status = KeWaitForMultipleObjects(2,pEvetObject,WaitAny,Executive,KernelMode,FALSE,NULL,NULL);
switch(Status)
{                
case 0:// new srb arrival
pltEntry = ExInterlockedRemoveHeadList(&g_ltProcSRBHead,&g_ltProcSRBLook);// remove entry

while(pltEntry)
{
pSrbExt = CONTAINING_RECORD(pltEntry,SRBEXT,m_ltEntry);

if(!ProcessSrb(pSrbExt->m_pMemDisk,pSrbExt->m_pSrb))
{
KdPrint(("[MemDisk] *******MemDiskRequestProcessorWorker...process return false\n"));
}
pltEntry = ExInterlockedRemoveHeadList(&g_ltProcSRBHead,&g_ltProcSRBLook);
}        
break;

case 1:// shutdown event
bBreak = TRUE;
break;
}

if(bBreak)
{
if(pExt && pExt->m_lpMemDisk)
{// Free MemDisk 's memory    
LoadOrSaveData(pExt,TRUE);
ExFreePoolWithTag(pExt->m_lpMemDisk,'ahaH');
}
break;
}
}
}

KdPrint(("[MemDisk] *******MemDiskRequestProcessorWorker...terminate worker thread\n"));
KeSetEvent(&g_ThreadExitEvent,IO_NO_INCREMENT,FALSE);
PsTerminateSystemThread(STATUS_SUCCESS);
}

// Get and set the parameters for the MemDisk
NTSTATUS MountMemDisk(PMEMDISK pExt)
{
NTSTATUS                Status=STATUS_SUCCESS;
SIZE_T                  MemLen=1024*1024*32;//32MB:You can modify this value

pExt->m_lpMemDisk=(PUCHAR)ExAllocatePoolWithTag(NonPagedPool,MemLen,'ahaH');
if(pExt->m_lpMemDisk!=NULL)
{
pExt->m_ulBlockShift = 9;//扇区字节数2 power 9=512
pExt->m_ulBlockCount = (ULONG)(MemLen/(1<<pExt->m_ulBlockShift));    
LoadOrSaveData(pExt,FALSE);    
}
else
{
KdPrint(("[MemDisk] *******MountMemDisk...ExAllocatePoolWithTag failed\n"));
Status=STATUS_INSUFFICIENT_RESOURCES;
}
return Status;
}

NTSTATUS LoadOrSaveData(PMEMDISK pExt,BOOLEAN bIsSaveData)
{
NTSTATUS            Status;
UNICODE_STRING        FileName;
OBJECT_ATTRIBUTES      InitAttrib;
HANDLE              FileHandle;
IO_STATUS_BLOCK      IoStatusBlock;

FILE_END_OF_FILE_INFORMATION     FileEndInfo;
FILE_STANDARD_INFORMATION        FileStandardInfo;
LARGE_INTEGER                      ByteOffset;

if(!pExt || !pExt->m_lpMemDisk)
{
KdPrint(("[MemDisk] *******LoadOrSaveData...STATUS_INVALID_PARAMETER\n"));    
return STATUS_INVALID_PARAMETER;
}

RtlInitUnicodeString(&FileName,L"\\DosDevices\\C:\\MemDisk.dat");
InitializeObjectAttributes(&InitAttrib,&FileName,OBJ_CASE_INSENSITIVE,NULL,NULL);

Status = ZwCreateFile( &FileHandle,
GENERIC_ALL,
&InitAttrib,
&IoStatusBlock,
NULL,
FILE_ATTRIBUTE_NORMAL,
0,
FILE_OPEN_IF,//open or create
FILE_RANDOM_ACCESS|FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0);
if(Status==STATUS_SUCCESS)
{
ByteOffset.QuadPart=0;
FileEndInfo.EndOfFile.QuadPart=1024*1024*32;
Status=ZwSetInformationFile(FileHandle,&IoStatusBlock,&FileEndInfo,sizeof(FILE_END_OF_FILE_INFORMATION),FileEndOfFileInformation);
if(Status==STATUS_SUCCESS )
{
if(bIsSaveData==TRUE)
{
KdPrint(("[MemDisk] *******LoadOrSaveData...Write data\n"));
Status = ZwWriteFile(FileHandle,NULL,NULL,NULL,&IoStatusBlock,pExt->m_lpMemDisk,1024*1024*32,&ByteOffset,NULL);
}
else
{
KdPrint(("[MemDisk] *******LoadOrSaveData...Read data\n"));                    
Status = ZwReadFile(FileHandle,NULL,NULL,NULL,&IoStatusBlock,pExt->m_lpMemDisk,1024*1024*32,&ByteOffset,NULL);                
}
}    
ZwClose(FileHandle);
}
if(Status!=STATUS_SUCCESS )
{
KdPrint(("[MemDisk] *******LoadOrSaveData...failed with code:%08X\n",Status));    
}    

return Status;
}

//**************************************************************************************
//    日期:    2010 /08 /21
//    创建:    ejoyc
//    描述:    ProcessSRB.c: MemDisk scsi process
//**************************************************************************************
#include "precomp.h"

// check bound
BOOLEAN CheckBound(PMEMDISK pExt,PSCSI_REQUEST_BLOCK pSrb,PULONG pulStart,PULONG pulLen)
{
PCDB pCdb10 = (PCDB)pSrb->Cdb;

*pulStart = *(PULONG)(&pCdb10->CDB10.LogicalBlockByte0);
REVERSE_LONG(pulStart);
*pulLen = *(PUSHORT)(&pCdb10->CDB10.TransferBlocksMsb);
REVERSE_SHORT(pulLen);

if(!*pulLen)
{
KdPrint(("[MemDisk] *******TestUnitReady..Length is a bad value\n"));
return FALSE;
}

if(*pulStart + *pulLen > pExt->m_ulBlockCount)
{
KdPrint(("[MemDisk] *******TestUnitReady..no media in device\n"));
return FALSE;
}
return TRUE;
}

/* // test unit ready
BOOLEAN TestUnitReady(PMEMDISK pExt,PSCSI_REQUEST_BLOCK pSrb)
{
if(pExt==NULL || NULL==pExt->m_lpMemDisk)
{
KdPrint(("[MemDisk] *******TestUnitReady..no media in device\n"));
}
return TRUE;
}
*/
// inquiry
BOOLEAN Inquiry(PMEMDISK pExt,PSCSI_REQUEST_BLOCK pSrb)
{
PINQUIRYDATA pInquiryData = (PINQUIRYDATA)pSrb->DataBuffer;    
if(pSrb->Lun)
{
KdPrint(("[MemDisk] *******Inquiry...(target,lun)=(%d,%d)..not supported\n",pSrb->TargetId,pSrb->Lun));
pSrb->SrbStatus = SRB_STATUS_SELECTION_TIMEOUT;
return TRUE;
}

if(pSrb->Cdb[1] & CDB_INQUIRY_EVPD)
{
KdPrint(("[MemDisk] *******Inquiry..not support evpd\n"));
return TRUE;
}

pInquiryData->DeviceType = DIRECT_ACCESS_DEVICE;
pInquiryData->DeviceTypeQualifier = DEVICE_CONNECTED;

pInquiryData->DeviceTypeModifier = 0;
pInquiryData->RemovableMedia = 0;
pInquiryData->ResponseDataFormat = 2;
pInquiryData->Versions = 0;
pInquiryData->AdditionalLength = sizeof(INQUIRYDATA) - 5;

//这个数据关系到虚拟磁盘在设备管理器中的显示信息
RtlMoveMemory(pInquiryData->VendorId,"ejoycLib",8);
RtlMoveMemory(pInquiryData->ProductId,"MemDisk          ",16);
RtlMoveMemory(pInquiryData->ProductRevisionLevel,"1010",4);

KdPrint(("[MemDisk] *******Inquiry...succeeded(target-lun)=(%d,%d)\n",pSrb->TargetId,pSrb->Lun));

return TRUE;
}

// read caps
BOOLEAN ReadCaps(PMEMDISK pExt,PSCSI_REQUEST_BLOCK pSrb)
{
PREAD_CAPACITY_DATA pReadCapsData;
ULONG ulValue;

if(pExt==NULL || NULL==pExt->m_lpMemDisk)
{
KdPrint(("[MemDisk] *******ReadCaps..no media in device\n"));
return TRUE;
}

pReadCapsData = (PREAD_CAPACITY_DATA)pSrb->DataBuffer;

ulValue = pExt->m_ulBlockCount - 1;//MBR占用一个扇区?
REVERSE_LONG(&ulValue);
pReadCapsData->LogicalBlockAddress = ulValue;

ulValue = 1 << pExt->m_ulBlockShift;
REVERSE_LONG(&ulValue);
pReadCapsData->BytesPerBlock = ulValue;

return TRUE;
}

// write or read OP
BOOLEAN DoMemDiskIO(PMEMDISK pExt,PSCSI_REQUEST_BLOCK pSrb,BOOLEAN bOpIsWrite)
{
PSRBEXT         pSrbExt        = (PSRBEXT)pSrb->SrbExtension;
ULONG             ulStart,ulLen;
LARGE_INTEGER     pos;

if(pExt==NULL || NULL==pExt->m_lpMemDisk)
{
KdPrint(("[MemDisk] *******DoMemDiskIO..no media in device\n"));
return FALSE;
}

if(!CheckBound(pExt,pSrb,&ulStart,&ulLen))
{
KdPrint(("[MemDisk] *******DoMemDiskIO..check bound failed\n"));
return FALSE;
}

pos.QuadPart = ulStart;//*******
pos.QuadPart <<= pExt->m_ulBlockShift;

if(bOpIsWrite)
{    
RtlMoveMemory(pExt->m_lpMemDisk+pos.QuadPart,pSrb->DataBuffer,pSrb->DataTransferLength);
}
else
{
RtlMoveMemory(pSrb->DataBuffer,pExt->m_lpMemDisk+pos.QuadPart,pSrb->DataTransferLength);
}    

pSrb->SrbStatus = SRB_STATUS_SUCCESS;
return TRUE;
}

// process io control
BOOLEAN DoIoControl(PMEMDISK pExt,PSCSI_REQUEST_BLOCK pSrb)
{
//KdPrint(("[MemDisk] *******DeviceIoControl,code 0x%x\n",((PSRB_IO_CONTROL)pSrb->DataBuffer)->ControlCode));
return TRUE;
}

// process scsi cmd
BOOLEAN DoScsiCmd(PMEMDISK pExt,PSCSI_REQUEST_BLOCK pSrb)
{
BOOLEAN bRet;
switch(pSrb->Cdb[0])
{
case 0x28:
bRet=DoMemDiskIO(pExt,pSrb,FALSE);
break;
case 0x2A:
bRet=DoMemDiskIO(pExt,pSrb,TRUE);
break;
case 0x25:
bRet=ReadCaps(pExt,pSrb);
break;
case 0x12:
bRet=Inquiry(pExt,pSrb);
break;
/*     case 0x00:
bRet=TestUnitReady(pExt,pSrb);
break; */
default:
//KdPrint(("[MemDisk] *******DoScsiCmd,code 0x%x\n",pSrb->Cdb[0]));
bRet=TRUE;
}
return bRet;
}

// process srb
BOOLEAN ProcessSrb(PMEMDISK pExt,PSCSI_REQUEST_BLOCK pSrb)
{
PSRBEXT pSrbExt        = (PSRBEXT)pSrb->SrbExtension;
BOOLEAN bRet        = TRUE;

pSrb->SrbStatus        = SRB_STATUS_SUCCESS;
pSrb->ScsiStatus    = SCSISTAT_GOOD;

switch(pSrb->Function)
{
case SRB_FUNCTION_SHUTDOWN:
KdPrint(("[MemDisk] *******SRB_FUNCTION_SHUTDOWN\n"));
break;

case SRB_FUNCTION_FLUSH:
KdPrint(("[MemDisk] *******SRB_FUNCTION_FLUSH\n"));
LoadOrSaveData(pExt,TRUE);
break;

case SRB_FUNCTION_EXECUTE_SCSI:
bRet =DoScsiCmd(pExt,pSrb);
break;

case SRB_FUNCTION_IO_CONTROL:
bRet = DoIoControl(pExt,pSrb);
break;
default:
pSrb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
//KdPrint(("[MemDisk] *******SRB_FUNCTION_unknow %d\n",pSrb->Function));
break;
}

ExInterlockedInsertTailList(&g_ltFinishSRBHead,&pSrbExt->m_ltEntry,&g_ltFinishSRBLock);
return bRet;
}

#-------------------------------分割线------------------------------------
#sources
TARGETNAME=MemDiskEx
TARGETTYPE=DRIVER

MSC_WARNING_LEVEL=/W3 /WX
#MSC_OPTIMIZATION=/Ox /Os /GT /arch:SSE2

TARGETLIBS= $(TARGETLIBS) \
$(DDK_LIB_PATH)\ntstrsafe.lib \
$(DDK_LIB_PATH)\scsiport.lib

SOURCES=helper.c ProcessSRB.c MemDiskEx.c
#
#-------------------------------分割线------------------------------------
#
;
; MemDiskEx.INF
; Installation INF for Virtual SCSI Controller for Windows XP/2003
; modified by ejoyc 
;

[Version]
signature="$CHICAGO$"
Class=SCSIAdapter
ClassGUID={4D36E97B-E325-11CE-BFC1-08002BE10318}
Provider=%INF_PROVIDER%
DriverVer=08/21/2010,1.0.0.1

[DestinationDirs]
DefaultDestDir = 12 ; DIRID_DRIVERS
MoveMiniPort.NTx86 = 12;

[Manufacturer]
%EJOYCLIB%=Standard

[Standard]
%EJOYCLIB.DeviceDesc%= EJOYCLIB,MemDiskEx,GEN_SCSIADAPTER,DETECTED\ejoycScsi

[EJOYCLIB]
AddReg=IOS

[EJOYCLIB.NTx86]
LogConfig=EJOYCLIB.LogConfigOverride
CopyFiles=MoveMiniPort.NTx86

[EJOYCLIB.NTx86.Services]
AddService = ejoycScsi, 2, ejoycScsi_Service_Inst, Miniport_EventLog_Inst

[MoveMiniPort.NTx86]
MemDiskEx.sys

[SourceDisksFiles]
MemDiskEx.sys = 1

[SourceDisksNames]
1 = %DISKNAME1%,,,,
2 = %DISKNAME2%,,,,

[ejoycScsi_Service_Inst]
ServiceType    = 1
StartType      = 1;/*很重要0,1,2*/
ErrorControl   = 1
ServiceBinary  = %12%\MemDiskEx.sys
LoadOrderGroup = SCSI Miniport
AddReg         = ejoycScsi_pnp

[ejoycScsi_pnp]
HKR, "Parameters\PnpInterface", "1", 0x00010001, 0x00000001

[EJOYCLIB.LogConfigOverride]
ConfigPriority = NORMAL
IOConfig      = 1@0-FFFF%FFFF(FFFF::)

[IOS]
HKR,,PortDriver,,EJOYCLIB.MPD
HKR,,DevLoader,,*IOS
HKR,,DontLoadIfConflict,,"Y"

;***************************************
[Miniport_EventLog_Inst]
AddReg = Miniport_EventLog_AddReg

[Miniport_EventLog_AddReg]
HKR,,EventMessageFile,0x00020000,"%%SystemRoot%%\System32\IoLogMsg.dll"
HKR,,TypesSupported,0x00010001,7

[Strings]
INF_PROVIDER="EJOYCLIB"
EJOYCLIB="EJOYCLIB"
FLOPPY_DESCRIPTION="EJOYCLIB Virtual SCSI Miniport Drivers Disk"
EJOYCLIB.DeviceDesc="EJOYCLIB Virtual SCSI Adapter Controller"
DISKNAME1="EJOYCLIB Virtual SCSI Controller Driver Disk#1"
DISKNAME2="Windows system"

#
#-------------------------------分割线------------------------------------
#
MemDisk/MemDiskEx:
+It is a scsi miniport driver and It can create a virtual scsi disk steadily;
+ It inherited from Tiamo's TiamoDisk project which can be found in the websit:http://bbs.driverdevelop.com
+ It is designed to create a virtual scsi disk and whose storage space is from the physical memory,so if you want to run this driver,please make sure there is enough availiable memory space in your pc.

version 1.0.0.1 [2010.08.21]
+ add a new function that the MemDisk can keep the data in itself even you reboot your pc;

version 1.0.0.0 [2010.08.21]
+ first release ;
+ Tool : WDK 7600.16385.1

[PS]My english is poor, I hope that you can understand me ;)