Some time ago, just use a new computer, due to limited funds did not match the long-desired SSD. I did not feel the feeling of flying, always reconciled, think carefully. I'm dead pretty large storage, we can assume that part of the memory as a hard drive to get it out. No faster than SSDs, let's start.
First of all. All we have to do is write a hard drive controller driver, we know. The driver of the storage type generally adheres to the structure of Class/port/miniport driver. Microsoft has finished the drive of the disk class, and the Port driver of the SCSI bus, we just need to complete the miniport drive of the hard disk controller on the SCSI bus.
Take out the source code analysis of DDK, Microsoft did not live up to provide a driver source, I use DDK 7600.16385.1, there is a RAMDisk source code, but read it found. It is implemented using the WDF framework. I'm not familiar with the WDF framework. decided to use the WDM framework to implement it again.
Then there is a variety of information inquiries. Finally, the general framework of the SCSI miniport drive is eventually ascertained. In order to give an extremely simple framework. I omitted a lot of redundant code, such as the following:
#define DBG 1#include <ntddk.h> #include <srb.h> #include <scsi.h> #define MODULE_NAME_PREFIX "Ramdis K: "#define Kdprintthisfunction () Kdprint ((module_name_prefix"%s\n ", __function__)) #define RAMDISK_SECTOR_SIZE 512 #define Ramdisk_capacity * 1024x768 *1024//typedef struct _device_extension {//} device_extension, *pdevice Some callback functions of the _extension;//Miniport Boolean Initialize (__in PVOID deviceextension); BOOLEAN Resetbus (__in PVOID deviceextension, __in ULONG pathid); BOOLEAN startio (__in PVOID deviceextension, __in pscsi_request_block Srb); BOOLEAN Interrupt (__in PVOID deviceextension); ULONG findadapter (__in PVOID deviceextension, __in PVOID hwcontext, __in PVOID businformation, __in PCHAR Arg Umentstring, __inout pport_configuration_information configinfo, __out pboolean Again); Boolean adapterstate (__in PVOID deviceextension, __in PVOID Context, __in BOOLEAN SaveState); Scsi_adapter_control_status Adaptercontrol (PVOID deviceextensIon,scsi_adapter_control_type ctltype,pvoid pparameters); VOID driverunload (__in struct _driver_object *driverobject); PVOID Ramdiskmemroy; NTSTATUS driverentry (__in struct _driver_object *driverobject, __in punicode_string registrypath) {hw_in Itialization_data Hwinitdata; Kdprintthisfunction (); RtlZeroMemory (&hwinitdata, sizeof (Hw_initialization_data)); hwinitdata.hwinitializationdatasize = sizeof (Hw_initialization_data); Hwinitdata.hwinitialize = Initialize; Hwinitdata.hwresetbus = Resetbus; Hwinitdata.hwstartio = Startio; Hwinitdata.hwinterrupt = NULL; Do not need to interrupt service hwinitdata.hwfindadapter = Findadapter; Hwinitdata.hwadapterstate = adapterstate; Hwinitdata.hwadaptercontrol = Adaptercontrol; Hwinitdata.adapterinterfacetype = Isa; hwinitdata.deviceextensionsize = 0; hwinitdata.srbextensionsize = 0; hwinitdata.numberofaccessranges = 0; Hwinitdata.mapbuffers = TRUE; Hwinitdata.needphysicaladdresSES = FALSE; hwinitdata.taggedqueuing = FALSE; Hwinitdata.autorequestsense = TRUE; Hwinitdata.multiplerequestperlu = FALSE; Hwinitdata.receiveevent = FALSE; Initialize Scsiportinitialize (DriverObject, Registrypath, &hwinitdata, NULL); Driverobject->driverunload = Driverunload; Ramdiskmemroy = ExAllocatePool (NonPagedPool, ramdisk_capacity); if (Ramdiskmemroy = = NULL) {Kdprint (("Ramdisk:allocate Memory failed!\n")); return status_failed_driver_entry; } kdprint (("myramdisk:ramdiskmemroy-0x%p\n", Ramdiskmemroy)); return status_success;} Voiddriverunload (__in struct _driver_object *driverobject) {kdprintthisfunction (); Exfreepool (Ramdiskmemroy);} BOOLEAN Initialize (__in PVOID deviceextension) {kdprintthisfunction (); return TRUE;} Booleanresetbus (__in PVOID deviceextension, __in ULONG pathid) {kdprintthisfunction (); return TRUE;} Booleanreadcapacitydata (Pscsi_request_block Srb) { Pread_capacity_data Capacitydata = (pread_capacity_data) srb->databuffer; ULONG Value = 0; Kdprintthisfunction (); This the value should in Big Endian value = ramdisk_capacity/ramdisk_sector_size-1; Reverse_long (&value); capacitydata->logicalblockaddress = Value; Value = ramdisk_sector_size; Reverse_long (&value); Capacitydata->bytesperblock = Value; return TRUE;} Booleaninquiry (Pscsi_request_block Srb) {pinquirydata inquirydata = (pinquirydata) srb->databuffer; pcdb Cdb = &Srb->Cdb; Kdprintthisfunction (); Inquirydata->devicetype = Direct_access_device; Inquirydata->devicetypequalifier = device_connected; Inquirydata->devicetypemodifier = 0; Inquirydata->removablemedia = 0; Inquirydata->responsedataformat = 2; inquirydata->versions = 0; inquirydata->additionallength = sizeof (Inquirydata)-5; These data relate to the display of the Device Manager in the system rtlmovememory (Inquirydata->vendorid, "HenzOX ", 6); RtlMoveMemory (Inquirydata->productid, "Ramdisk-henzox", 16); RtlMoveMemory (Inquirydata->productrevisionlevel, "1010", 4); Kdprint ("inquiry:succeeded (Target-lun) = (%d,%d) \ n", Srb->targetid, Srb->lun)); return TRUE;} Booleanreaddisk (Pscsi_request_block Srb) {ULONG Start = 0; Start sector USHORT Count = 0; Read size, in sectors pcdb Cdb = &Srb->Cdb[0]; Start = * (Pulong) &cdb->cdb10. LOGICALBLOCKBYTE0; Reverse_long (&start); Count = * (Pushort) &cdb->cdb10. TRANSFERBLOCKSMSB; Reverse_short (&count); if (Start + Count) * ramdisk_sector_size > Ramdisk_capacity) {kdprint (("readdisk:overflow!\n")); return FALSE; }//Count * ramdisk_sector_size equals to Srb->datatransferlength Kdprint (("Readdisk:start-%d, SIZE-%d\n", Start * ramdisk_sector_size, srb->datatransferlength)); RtlMoveMemory (Srb->databuffer, (Puchar) Ramdiskmemroy + Start * RAMDIsk_sector_size, srb->datatransferlength); return TRUE;} Booleanwritedisk (Pscsi_request_block Srb) {ULONG Start = 0; Start address USHORT Count = 0; Read size, in sectors pcdb Cdb = &Srb->Cdb[0]; Start = * (Pulong) &cdb->cdb10. LOGICALBLOCKBYTE0; Reverse_long (&start); Count = * (Pushort) &cdb->cdb10. TRANSFERBLOCKSMSB; Reverse_short (&count); if (Start + Count * ramdisk_sector_size > Ramdisk_capacity) {kdprint (("writedisk:overflow!\n")); return FALSE; } kdprint (("Writedisk:start-%d, Size-%d\n", Start * ramdisk_sector_size, srb->datatransferlength)); RtlMoveMemory ((Puchar) Ramdiskmemroy + Start * ramdisk_sector_size, Srb->databuffer, srb->datatransferlength); return TRUE;} BOOLEANEXECUTESCSI (Pscsi_request_block Srb) {BOOLEAN returnvalue = FALSE; PCDB Cdb = (pcdb) &Srb->Cdb[0]; Kdprintthisfunction (); Switch (CDB->CDB10. OperationcODE) {case 0x28://Read Disk returnvalue = Readdisk (SRB); Break Case 0x2A://Write Disk returnvalue = Writedisk (SRB); Break Case 0X25://Read The capacity of the disk returnvalue = Readcapacitydata (SRB); Break Case 0x12://Disk Inquiry returnvalue = inquiry (SRB); Break Default:kdprint ("Executescsi:unknown operation code (0x%p) \ n", Cdb->cdb10. Operationcode)); returnvalue = TRUE; } return returnvalue;} Booleandoiocontrol (Pscsi_request_block Srb) {kdprintthisfunction (); return TRUE;} Boolean startio (__in PVOID deviceextension, __in Pscsi_request_block Srb) {Boolean returnvalue = TRUE; Kdprintthisfunction (); Srb->srbstatus = srb_status_success; Srb->scsistatus = Scsistat_good; Switch (srb->function) {Case Srb_function_shutdown:kdprint (("startio:srb_function_shutdown\n")); Break Case Srb_fuNction_flush:kdprint (("startio:srb_function_flush\n")); Break Case SRB_FUNCTION_EXECUTE_SCSI://Run SCSI Command returnvalue = EXECUTESCSI (SRB); Break Case srb_function_io_control:srb->srbstatus = srb_status_pending; returnvalue = Doiocontrol (SRB); Break Default:srb->srbstatus = Srb_status_invalid_request; } scsiportnotification (Requestcomplete, deviceextension, SRB); Scsiportnotification (Nextrequest, deviceextension); return returnvalue;} Booleaninterrupt (__in PVOID deviceextension) {kdprintthisfunction (); return TRUE;} ULONG findadapter (__in PVOID deviceextension, __in PVOID hwcontext, __in PVOID businformation, __in PCHAR Arg Umentstring, __inout pport_configuration_information configinfo, __out Pboolean Again) {kdprintthisfunction () ; Configinfo->adapterinterfacetype = Isa; Configinfo->alignmentmask = 0x00000003; Configinfo->autorequestseNSE = TRUE; configinfo->bufferaccessscsiportcontrolled = FALSE; Configinfo->businterruptlevel = 0; Configinfo->businterruptvector = 0; configinfo->dma32bitaddresses = TRUE; Configinfo->master = TRUE; Configinfo->cachesdata = TRUE; configinfo->numberofbuses = 1; Configinfo->maximumnumberoftargets = 1; Configinfo->maximumtransferlength = 0x10000; Configinfo->multiplerequestperlu = FALSE; Configinfo->numberofphysicalbreaks = 0x00f8; Configinfo->scattergather = TRUE; configinfo->taggedqueuing = FALSE; *again = FALSE; return sp_return_found;} Scsi_adapter_control_status Adaptercontrol (PVOID deviceextension, Scsi_adapter_control_type CtlType, PVOID Param eters) {pscsi_supported_control_type_list scsilist=null; Scsi_adapter_control_status STATUS = scsiadaptercontrolsuccess; Kdprintthisfunction (); Switch (Ctltype<span style= "font-family:arial, Helvetica, Sans-serif;" >) </SPAN> {Case Scsiquerysupportedcontroltypes:kdprint (("adaptercontrol:scsiquerysupportedcontroltypes\n")); Scsilist = (pscsi_supported_control_type_list) Parameters; <span style= "font-family:arial, Helvetica, Sans-serif;" >scsilist</span>->supportedtypelist[scsistopadapter] = TRUE; Scsilist->supportedtypelist[scsirestartadapter] = TRUE; Scsilist->supportedtypelist[scsiquerysupportedcontroltypes] = TRUE; Break Case Scsistopadapter:kdprint (("adaptercontrol:scsistopadapter\n")); Break Case Scsirestartadapter:kdprint (("adaptercontrol:scsirestartadapter\n")); Break Default:status = scsiadaptercontrolunsuccessful; Break } return status; Booleanadapterstate (__in PVOID deviceextension, __in PVOID Context, __in BOOLEAN SaveState) {KDPRINTTHISF Unction (); return TRUE;}
Briefly explain. Scsiminiport Drive In fact very easy, that is, call Scsiportinitialize initialization, after the completion of a variety of SRB command can be, the source code originally wanted to use Chinese gaze and English gaze mixed. It was a bad habit of mine, but it was a clear stare. Very easy to read and understand.
After compiling it. can be installed directly. Then a new disk will appear in Disk Management. Initialize this disk to be able, I only set up 16M to implement, can change the source code to reach the size you want. It is quite good to use it as a temporary folder storage disk for your browser. Each time it restarts, the disk is destroyed, and in Microsoft's WDF source code there is the source code that makes the disk self-initializing. You can also add some other features, such as shutting down the features in the disk to a file, restarting the device and then loading it. The curing effect can be achieved. In fact, there are a lot of mature products on the internet can be used, write one yourself but for the sake of practice, the driver did not undergo a lot of testing, which may lead to blue screen, and it can also be changed on the virtual machine.
Copyright notice: This article blog original articles, blogs, without consent, may not be reproduced.
SCSI Miniport driving a simple frame