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

📄 vdiskmp.c

📁 SCSI 的虚拟磁盘驱动 需要 windows DDK 很易懂的 DDK 文件结构
💻 C
📖 第 1 页 / 共 5 页
字号:
/////////////////////////////////////////////////////////////////////////////
//
// This source code (including its associated software) is owned by
// StorageCraft and is protected by United States and international
// intellectual property law, including copyright laws, patent laws,
// and treaty provisions.
//
// vdiskmp.c
//
// StorageCraft Virtual SCSI miniport
//
// Harddisk in a file. Emulate new SCSI disk. 
// Created as example of using VSPORT.LIB
//
// www.storagecraft.com
//
/////////////////////////////////////////////////////////////////////////////
//
// Install: 
// 
// 1. Save to the Registry:
//
// \Registry\Machine\SYSTEM\CurrentControlSet\Services\vdiskmp\Target0\LUN0
//
//        Filename        SZ      "\??\C:\VDISK\Files\My Documents.dsk"
//        or
//        Filename        SZ      "C:\VDISK\Files\My Documents.dsk"
//        Size            DW      100   (In Megabytes)          
//        ReadOnly        DW      0
//
// 2. Use Add Hardware wizard to add new SCSI device and select vdiskmp.inf. 
//
// Notice:
//
// You must go to Disk Administrator to partition and format this new disk.
// After it you will see new drive letter(s) in the My Computer window.
//
// If driver can't start LUN from the Registry path it will remove this LUN from 
// the Registry
//
//////////////////////////////////////////////////////////////////////////////
//
// Functions:
// VdiskReadRegistryParameters
// VdiskRemoveLunFromRegistry
// VdiskInquiryLun
// VdiskMpInitialize
// VdiskMpStartIo
// VdiskMpInquiry
// VdiskMpNewDevice
// VdiskShutdownLun
// VdiskMpResetBus
// DriverEntry
// VdiskRequestExecute
// VdiskRequestThread
// VdiskRequestSubmit
// VdiskRequestDeleteAll
// VdiskFillSenseData
// 
// PnP functions for W2K:
// VdiskMpStopDevice
// VdiskMpRestartDevice
// VdiskMpDestroyLun
//
// Functions for WMI support:
// VdiskMpWmiAdapterQueryDataBlock
// VdiskMpWmiAdapterExecuteMethod
// VdiskMpWmiLunQueryDataBlock
// VdiskMpWmiLunExecuteMethod
// VdiskMpWmiStartIo
// VdiskSetRegistryParameters
// VdiskMpWmiCreateDisk
//
/////////////////////////////////////////////////////////////////////////////

#if DBG
// Time-stamp the object module in the debug build.
#pragma comment (user, __FILE__ " compiled on " __TIMESTAMP__) 
#endif

#pragma warning (disable : 4115 4214 4514)
#ifdef VSPORT_PNP
#include <initguid.h>
#endif
#include <wchar.h>
#include <ntddk.h>
#include <scsi.h>
#include <devioctl.h>
#include <ntdddisk.h>
#include <ntddscsi.h>
#ifdef VSPORT_PNP
#include <wmistr.h>
#endif
#include <vsport.h>
#include "vdiskmp.h"
#pragma warning (default : 4115 4214)

// Path in the Registry to save disks' parameters
const WCHAR szVdiskLunPath[] = L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services\\vdiskmp\\Target%u\\LUN%u";

#ifdef VSPORT_PNP

// WMI GUID for adapter
// Same as in MOF file
// {DF64F3DC-C38B-47ee-86EE-A6E1E194D036}
DEFINE_GUID(VDISKMP_WMI_ADAPTER_GUID, 
        0xDF64F3DC, 0xC38B, 0x47ee, 0x86, 0xee, 0xa6, 0xe1, 0xe1, 0x94, 0xd0, 0x36);

// WMI GUID for LUN
// Same as in MOF file
// {88289602-D30C-4aec-8DF3-22D998440CE4}
DEFINE_GUID(VDISKMP_WMI_LUN_GUID, 
        0x88289602, 0xd30c, 0x4aec, 0x8d, 0xf3, 0x22, 0xd9, 0x98, 0x44, 0x0c, 0xe4);

// WMI functions

// WMI callback to query the adapter data block
static NTSTATUS VdiskMpWmiAdapterQueryDataBlock(PVOID DeviceOrLunExtension,
                                                        PVSPORT_WMI_REQUEST Request,
                                                        ULONG BufferAvail, PUCHAR Buffer);
// WMI callback to execute the adapter method
static NTSTATUS VdiskMpWmiAdapterExecuteMethod(PVOID DeviceOrLunExtension,
                                                        PVSPORT_WMI_REQUEST Request,
                                                        ULONG InBufferSize, PUCHAR Buffer);
// WMI callback to query the LUN data block
static NTSTATUS VdiskMpWmiLunQueryDataBlock(PVOID DeviceOrLunExtension,
                                                        PVSPORT_WMI_REQUEST Request,
                                                        ULONG BufferAvail, PUCHAR Buffer);
// WMI callback to execute the LUN method
static NTSTATUS VdiskMpWmiLunExecuteMethod(PVOID DeviceOrLunExtension,
                                                        PVSPORT_WMI_REQUEST Request,
                                                        ULONG InBufferSize, PUCHAR Buffer);
// WMI SRB processing function
static VOID VdiskMpWmiStartIo(PVOID DeviceExtension, PSCSI_WMI_REQUEST_BLOCK Srb);
// CreateDisk WMI method body
static NTSTATUS VdiskMpWmiCreateDisk(PVOID MiniportDeviceExtension, PWSTR Name, ULONG NameLengthInBytes, UINT32 SizeInMegs);

// WMI constant structures

// Adapter GUID array
static VSPORT_WMI_GUID VdiskMpWmiAdapterGuid = 
{
    // Guid
    &VDISKMP_WMI_ADAPTER_GUID,
    // InstanceCount
    1,
    // Flags
    WMIREG_FLAG_INSTANCE_PDO
};

// LUN GUID array
static VSPORT_WMI_GUID VdiskMpWmiLunGuid = 
{
    // Guid
    &VDISKMP_WMI_LUN_GUID,
    // InstanceCount
    1,
    // Flags
    WMIREG_FLAG_INSTANCE_PDO
};

// Adapter WMI descriptor
static VSPORT_WMI_CONTEXT VdiskMpWmiAdapter = 
{
    // DefaultFlags
    WMIREG_FLAG_INSTANCE_PDO,
    // BaseInstanceName
    NULL,
    // MofResourceName
    L"WmiResource",
    // GuidCount
    1,
    // GuidList
    &VdiskMpWmiAdapterGuid,
    // QueryDataBlock
    VdiskMpWmiAdapterQueryDataBlock,
    // SetDataBlock
    NULL,
    // SetDataItem
    NULL,
    // ExecuteMethod
    VdiskMpWmiAdapterExecuteMethod,
    // FunctionControl
    NULL
};

// LUN WMI descriptor
static VSPORT_WMI_CONTEXT VdiskMpWmiLun = 
{
    // DefaultFlags
    WMIREG_FLAG_INSTANCE_PDO,
    // BaseInstanceName
    NULL,
    // MofResourceName
    L"WmiResource",
    // GuidCount
    1,
    // GuidList
    &VdiskMpWmiLunGuid,
    // QueryDataBlock
    VdiskMpWmiLunQueryDataBlock,
    // SetDataBlock
    NULL,
    // SetDataItem
    NULL,
    // ExecuteMethod
    VdiskMpWmiLunExecuteMethod,
    // FunctionControl
    NULL
};

#endif

// Miniport initilization routine.
static BOOLEAN VdiskMpInitialize(PVOID DeviceExtension);
// Device drivers entry routine.
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath);

#ifdef ALLOC_PRAGMA
// Throw these functions away.
#pragma alloc_text(INIT, DriverEntry)
#endif

// Functions internal for this file

// Executes a single system thread request
// Called by the system thread
// Returns TRUE if the system thread must quit
static BOOLEAN VdiskRequestExecute(PVDISK_LUN_REQUEST Request, PVDISK_LUN_EXTENSION Lun, 
                                    PTHREAD_STORAGE Storage);
// The system thread function to process requests
// Context is not used
static VOID VdiskRequestThread(PVOID Context);
// Submits the request to the system thread
// Request will be executed asynchronously
static VOID VdiskRequestSubmit(PVDISK_LUN_REQUEST Request, PVDISK_LUN_EXTENSION Lun);
// Fill inquiry data
static VOID VdiskInquiry(PINQUIRYDATA InquiryData);
// Delete all requests
static VOID VdiskRequestDeleteAll(PVDISK_LUN_EXTENSION Lun);
// Fills the SENSE INFO for a CHECK CONDITION failure
static VOID VdiskFillSenseData(PSENSE_DATA SenseData, PSCSI_REQUEST_BLOCK Srb, ULONG Asc);
// Process shutdown LUN
static VOID VdiskShutdownLun(PVDISK_LUN_EXTENSION Lun, BOOLEAN WaitForThread);
// Reset BUS
static BOOLEAN VdiskMpResetBus(PVOID DeviceExtension, ULONG PathId);

// Put bytes back to front, big-endian to little-endian and vice versa
static ULONG VdiskChangeBytes(ULONG Size)
{
    return (((PUCHAR)&Size)[0] << 24) | (((PUCHAR)&Size)[1] << 16 ) |
           (((PUCHAR)&Size)[2] << 8)  |  ((PUCHAR)&Size)[3];
}

// Calculate index of array
static ULONG VdiskLun2Index(UCHAR TargetId, UCHAR Lun)
{
  ASSERT(TargetId < NUMBER_OF_TARGETS);
  ASSERT(Lun < NUMBER_OF_LUNS);
  return (ULONG)TargetId * NUMBER_OF_LUNS + Lun;
}

///////////////////////////////////////////////////////////////////////////////
// Read data from the Registry for the LUN
//
static NTSTATUS VdiskReadRegistryParameters(UCHAR TargetId, UCHAR LunId, PWSTR SzFileName,
                                        ULONG * DiskSize, BOOLEAN * ReadOnly)
{
    NTSTATUS Status;
   	ULONG Length;
    ULONG BufferSize;
    PVOID Buffer;
	UNICODE_STRING Str;
    OBJECT_ATTRIBUTES ObjectAttributes;
    HANDLE DiskKeyHandle;
    union {PVOID buffer; PKEY_VALUE_PARTIAL_INFORMATION valueKeyPartialInf;} u;
    // Start out with one page of buffer
    BufferSize = PAGE_SIZE;
    // Allocate this buffer
    u.buffer = ExAllocatePoolWithTag(PagedPool, BufferSize, 'Den1');
    // Check status
    if (u.buffer == NULL)
    {
        KdPrint(("VdiskReadRegistryParameters: Can't allocate buffer!\r\n"));
        return STATUS_INSUFFICIENT_RESOURCES;
    }
    // Format Registry path
    swprintf(u.buffer, szVdiskLunPath, TargetId, LunId);
    KdPrint(("VdiskReadRegistryParameters: %ls\r\n", u.buffer));
    // Open the key
    RtlInitUnicodeString(&Str, u.buffer);
    InitializeObjectAttributes(&ObjectAttributes, &Str, OBJ_CASE_INSENSITIVE, NULL, NULL);
    Status = ZwOpenKey(&DiskKeyHandle, KEY_READ, &ObjectAttributes);
	if (!NT_SUCCESS(Status))
    {
        KdPrint(("VdiskReadRegistryParameters: Can't open disk key! 0x%X\r\n", Status));
        ExFreePool(u.buffer);
		return Status;
    }
    // Query the filename value
	RtlInitUnicodeString(&Str, L"Filename");
	Status = ZwQueryValueKey(DiskKeyHandle, &Str, KeyValuePartialInformation,
                                u.valueKeyPartialInf, BufferSize, &Length);
	if (!NT_SUCCESS(Status) || (u.valueKeyPartialInf->Type != REG_SZ))
    {
		KdPrint(("VdiskReadRegistryParameters: Can't get file name!\r\n"));
        ZwClose(DiskKeyHandle);
        ExFreePool(u.buffer);
        return Status;
    }
    // Retrieve the value
	if ((((PWSTR)u.valueKeyPartialInf->Data)[0] == L'\\') && 
        (((PWSTR)u.valueKeyPartialInf->Data)[1] == L'?'))
    {
        // Filename in the Reqistry already contains "\??\" prefix
        wcscpy( SzFileName, (PWSTR)&(u.valueKeyPartialInf->Data));
    }
    else
    {
        // Insert prefix
        wcscpy(SzFileName, L"\\??\\");
	    wcscat(SzFileName, (PWSTR)&(u.valueKeyPartialInf->Data));
    }
    // Query the disk size value
    RtlInitUnicodeString(&Str, L"Size");

⌨️ 快捷键说明

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