//=============================================================================
//
// 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.
//
//=============================================================================
// RFSDUTIL.C - Utility routines for Registry File System
// Copyright (c) 1996, Compuware Corporation
#include "ramdisk.h"
#include PAGEABLE_CODE_SEGMENT
#include PAGEABLE_DATA_SEGMENT
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Function
// SetupDCB
//
// Purpose
// Initializes fields of a DCB passed to the port driver on an
// AEP_INQUIRY call.
//
// Parameters
// pDcb address of the DCB to initialize
//
// Return Value
// nonen
//
// Remarks
// The upper IOS layers are fairly sensitive the values inserted
// into the DCB by this routine. The fields must be consistent with
// values supplied in the INF file and the DRP, or the upper layers
// may ignore or unconfig the DCB. What's not clear is exactly which
// parameters have a critical role.
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Function
// AssociateDriveLetter
//
// Purpose
// Associate a drive letter with a DCB
//
// Parameters
// pDcb pointer to the DCB
//
// Return Value
// Returns the assigned drive letter code (A=0).
//
// Remarks
// To do this requires two calls to the IOS service routine in
// the first field of the ILB. The first call grabs the next
// free drive letter, and the second call binds the DCB to that
// drive letter.
//
// It has been observed that previously configured network shares
// may end up conflicting with the RFSD upon booting after the
// initial installation. This is not serious - simply redefine the
// shares to the next letter.
//
// A port driver should not really have to do this - the DISKTSD
// (or voltrack?) should take care of it automatically. Again,
// it is not clear exactly what the requirements are for having the
// IOS automatically assign a drive letter, but this approach seems
// to work fine.
//
/*
BYTE AssociateDriveLetter(DCB_COMMON* pDcb)
{
ISP_pick_drive_letter PDisp;
ISP_dcb_associate ADisp;
// Set up an ISP to grab the next free drive letter and send it.
////=============================================================================
//
// 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
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;
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.
// 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);
++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
//=============================================================================
//
// 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.
//
//=============================================================================
// RAMDISK.H - include file for the Registry File System driver
// Copyright (c) 1996 Compuware Corporation
// Constants required by the VtoolsD framework
#define RAMDISK_Major 1
#define RAMDISK_Minor 0
#define RAMDISK_DeviceID UNDEFINED_DEVICE_ID
#define RAMDISK_Init_Order UNDEFINED_INIT_ORDER
// Constants for the Device Registration Packet
#define RAMDISK_NAME "RAMDISK "
#define RAMDISK_REV 1
#define RAMDISK_FEATURE 0
#define RAMDISK_IFR 0
#define DISKSIZE 3*1024*1024
// Size of the buffer used to read in value data
#define READBUFSIZE 512
// Macro to define the byte offset from the start of an IOP to the
// start of the embedded IOR. Assumes no IOP extension.
//#define IORDELTA ((ULONG)(&((IOP*)0)->IOP_ior))
// Special value to denote the real root of the Registry, i.e., the
// implied root below the six predefined roots.
//#define REGISTRY_ROOT 0xffffffff
/*
// Macros for debugging
#ifdef DEBUG
// Display the string s and variable t
#define fsdtrace(s, t) dprintf("%s: pir=%x\n", s, t)
// Force a heap walk (use in conjunction with .m? command in debugger)
#define ForceHeapWalk(s) free(malloc(1));dprintf(s);DebugBreak()
#else // non-debug versions are empty
#define fsdtrace(s, t)
#define ForceHeapWalk(s)
#endif
*/
/////////////////////////////////////////////////////////////////////
// Types
typedef struct tagBPB
{ // BIOS parameter block
WORD secsize; // 00 sector size
BYTE clustsize; // 02 cluster size (in sectors)
WORD numrsv; // 03 # reserved sectors
BYTE numfat; // 05 # FATs
WORD numfiles; // 06 # entries in root directory
WORD numsectors; // 08 # sectors on disk
BYTE media; // 0A media descriptor
WORD fatsectors; // 0B # sectors in each FAT
} BPB, *PBPB; // BIOS parameter block [0D]
typedef struct tagPARTITION
{ // partition record
BYTE indicator; // 00 boot indicator (80 = active partition)
BYTE starthead; // 01 start head
BYTE startsec; // 02 bits 0-5: start sector, bits 6-7: bits 8-9 of start track
BYTE starttrack; // 03 bits 0-7 of start track
BYTE parttype; // 04 partition type
BYTE endhead; // 05 end head
BYTE endsec; // 06 end sector
BYTE endtrack; // 07 end track
DWORD bias; // 08 sector bias to start of partition
DWORD partsize; // 0C partition size in sectors
} PARTITION, *PPARTITION;
typedef struct tagBOOTSECT
{ // boot sector
BYTE jmpinst[3]; // 00 JMP to boot code
char vendid[8]; // 03 vendor id
struct tagBPB; // 0B bios parameter block
WORD tracksectors; // 18 # sectors per track
WORD numtracks; // 1A # heads (tracks)
DWORD numhidden; // 1C # hidden sectors
DWORD totsectors; // 20 # sectors if disk > 32 MB
BYTE drive; // 24 physical drive #
BYTE rsv1; // 25 reserved
BYTE xboot; // 26 extended boot signature (29h)
DWORD volid; // 27 volume ID
char label[11]; // 2B volume label
char fattype[8]; // 36 FAT12 or FAT16 plus 3 spaces
BYTE junk[384]; // 3E other stuff, including bootstrap loader
PARTITION part[4]; // 1BE partition table
WORD signature; // 1FE signature (0xAA55)
} BOOTSECT, *PBOOTSECT; // boot sector [200]
/*
//the structure of the direct_entry.
typedef struct _DIR_ENTRY
{
UCHAR deName[8]; // File Name
UCHAR deExtension[3]; // File Extension
UCHAR deAttributes; // File Attributes
UCHAR deReserved; // Reserved
USHORT deTime; // File Time
USHORT deDate; // File Date
USHORT deStartCluster; // First Cluster of file
ULONG deFileSize; // File Length
}DIR_ENTRY, *PDIR_ENTRY;
*/
/*
// Declare the device parameters structure. This is defined by DOS,
// and used for IOCTL calls.
typedef struct tagDeviceParams
{
BYTE dpSpecFunc;
BYTE dpDevType;
WORD dpDevAttr;
WORD dpCylinders;
BYTE dpMediaType;
WORD dpBytesPerSector;
BYTE dpSectorsPerCluster;
WORD dpReservedSectors;
BYTE dpFATs;
WORD dpRootDirectoryEntries;
WORD dpSectors;
BYTE dpMedia;
WORD dpSectorsPerFAT;
WORD dpSectorsPerTrack;
WORD dpHeads;
DWORD dpHiddenSectors;
DWORD dpHugeSectors;
} DEVICEPARAMS, *PDEVICEPARAMS;
*/
/*
// Declare the media ID structure. This is defined by DOS, and used
// for IOCTL calls.
typedef struct tagMediaID
{
WORD midInfoLevel;
DWORD midSerialNum;
CHAR midVolLable[11];
CHAR midFileSysType[8];
} MEDIAID, *PMEDIAID;
*/
/*
// RAMDISK private handle structure for FindFirst/FindNext operations
typedef struct _findcontext
{
ULONG fc_sig; // must be SIGFIND
HKEY fc_hkey; // registry key
HKEY fc_index; // subkey index
PWORD fc_match; // meta match specification
BOOL fc_bKeysDone; // TRUE if all keys enumerated
} FINDCONTEXT, *PFINDCONTEXT;
*/
/*
// RAMDISK private handle structure for Open File operations
typedef struct _regfsdhandle
{
ULONG h_sig; // must be SIGFILE
HKEY h_key; // registry KEY
PCHAR h_value; // value name
ULONG h_size; // value size
ULONG h_pos; // current position
} RAMDISKHANDLE, *PRAMDISKHANDLE;
*/
/////////////////////////////////////////////////////////////////////
// Global data
// Assigned drive letter designator (0=A)
//extern BYTE Drive;
// Pointer the drive's physical DCB
//extern DCB* pDcbOfThisDevice;
// Array of names of the six predefined Registry root keys
//extern PCHAR PredefinedRegKeyStrings[NPREDEFKEYS];
// Array of values of the six predefined Registry root keys
//extern INT PredefinedRegKeyValues[NPREDEFKEYS];
// The volume handle passed to the mount routine
//extern VRP* VolumeHandle;
// The driver's IOS linkage block
extern ILB RAMDISK_Ilb;
网上找到的C++代码,牛人看看其原理可以虚拟磁盘,转换为VB.NET代码吗//=============================================================================
//
// 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.
//
//=============================================================================
// RAMDISK.C - main module for VxD RAMDISK
// Copyright (c) 1996, Compuware Corporation
// This is the main module for the Registry File System Driver (RFSD).
// RFSD presents the system Registry as file volume mounted on a hard
// drive under Windows 95. It does this by first creating a virtual
// drive, and then installing a file system on that virtual drive. The
// file system maps file i/o calls to the system Registry. Specifically,
// directories are mapped to keys, files to values, and file contents
// to value data.
//
// RFSD is both a file system driver and a layered block device driver.
// As a file system driver, it translates file i/o requests into
// calls to services that access the Registry. As a port driver, it
// simulates the existence of a hard drive, and provides routines to
// handle i/o requests to that drive.
// The driver may be built with either Microsoft Visual C++ 2.0 (or
// later) or Borland C++ 4.02 (or later).
// Here we declare key data structures for the driver. This macro
// invocation defines the Device Data Block for the VxD, the Device
// Registration Packet (DRP), and the IOS Linkage Block (ILB).
// The macro is defined in vtoolsc.h.
Declare_Port_Driver(RAMDISK,DRP_ESDI_PD,RAMDISK_NAME,\
RAMDISK_REV,RAMDISK_FEATURE,RAMDISK_IFR,DRP_BT_ESDI,0)
// Set prototype for control message handler
DefineControlHandler(SYS_DYNAMIC_DEVICE_INIT, OnSysDynamicDeviceInit);
DefineControlHandler(SYS_DYNAMIC_DEVICE_EXIT, OnSysDynamicDeviceExit);
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Function
// ControlDispatcher
//
// Purpose
// Handles control messages sent by the system
//
// Parameters
// dwControlMessage message identifier
// register parameters
//
// Return Value
// The meaning of the return value varies depending on the
// message, but in general, TRUE means success.
//
// Remarks
// Like most all layered block device drivers, this driver
// processes only SYS_DYNAMIC_DEVICE_INIT.
//
BOOL __cdecl ControlDispatcher(
DWORD dwControlMessage,
DWORD EBX,
DWORD EDX,
DWORD ESI,
DWORD EDI,
DWORD ECX)
{
START_CONTROL_DISPATCH
ON_SYS_DYNAMIC_DEVICE_INIT(OnSysDynamicDeviceInit);
ON_SYS_DYNAMIC_DEVICE_EXIT(OnSysDynamicDeviceExit);
END_CONTROL_DISPATCH
return TRUE;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Function
// OnSysDynamicDeviceInit
//
// Purpose
// First level initialization of the RFSD
//
// Parameters
// None
//
// Return Value
// Returns TRUE if successful.
//
// Remarks
// There are two tasks to accomplish. First, the driver must
// register with the IFSMgr. If this is successful, the driver
// registers with the I/O Supervisor.
//
char base[DISKSIZE];
BOOL OnSysDynamicDeviceInit()
{
int add_i, nsec;
USHORT fatEntries;
USHORT fatSectorCnt;
PUCHAR firstFatSector;
PBOOTSECT bsp;
PWORD fat;
// Fill in dummy boot sector so we look like a disk
bsp->jmpinst[0] = 0xEB;
bsp->jmpinst[1] = 0x3C;
bsp->jmpinst[2] = 0x90;
memcpy(bsp->vendid, "WALTONEY", 8);
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 = (DWORD) base; // use base address as volume ID
memcpy(bsp->label, "NO NAME ", 11);
memcpy(bsp->fattype, "FAT16 ", 8);
// Now register with the IOS, passing a pointer to the Device
// Registration Packet that is declared above using macro
// Declare_Port_Driver. No error returns are defined for this call.
IOS_Register(&RAMDISK_Drp);
// Return TRUE to indicate a successful initialization.