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

📄 vscsi.c

📁 虚拟Scsi Disk源程序 版权归原作者
💻 C
📖 第 1 页 / 共 2 页
字号:
// vscsi.c
//
// Generated by C DriverWizard 3.2.0 (Build 2485)
// Requires DDK Only
// File created on 5/18/2005
//

#include "pch.h"
#ifdef VSCSIDISK_WMI_TRACE
#include "VScsiDisk.tmh"
#endif
#pragma warning(disable : 4995)
#define VSCSI_BUFFER_SIZE   (0x40000000/16)
UCHAR g_Buffer[VSCSI_BUFFER_SIZE];


///////////////////////////////////////////////////////////////////////////////////////////////////
//  VScsiDiskScsiDeviceIoControlDispatch
//      IRP_MJ_DEVICE_CONTROL handler
//
//  Arguments:
//      IN  DeviceObject
//              our PDO device object
//
//      IN  Irp
//              IRP_MJ_DEVICE_CONTROL irp
//
//  Return Value:
//      Status
//
NTSTATUS VScsiDiskScsiDeviceIoControlDispatch(
    IN  PDEVICE_OBJECT  DeviceObject,
    IN  PIRP            Irp
    )
{
    NTSTATUS                    status;
    PIO_STACK_LOCATION          irpStack;
    PSTORAGE_PROPERTY_QUERY     query;
    PSTORAGE_DESCRIPTOR_HEADER  header;
    PSTORAGE_ADAPTER_DESCRIPTOR adapterDescriptor;
    PSTORAGE_DEVICE_DESCRIPTOR  deviceDescriptor;

    VScsiDiskDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"++. IRP %p", Irp);

    irpStack = IoGetCurrentIrpStackLocation(Irp);
	VScsiDiskDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__" %d", irpStack->Parameters.DeviceIoControl.IoControlCode);
    Irp->IoStatus.Information = 0;

    switch (irpStack->Parameters.DeviceIoControl.IoControlCode)
    {
    case IOCTL_STORAGE_QUERY_PROPERTY:
        query = (PSTORAGE_PROPERTY_QUERY)Irp->AssociatedIrp.SystemBuffer;
        header = (PSTORAGE_DESCRIPTOR_HEADER)Irp->AssociatedIrp.SystemBuffer;

        if ((query->PropertyId == StorageAdapterProperty) && (query->QueryType == PropertyStandardQuery))
        {
			VScsiDiskDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__" StorageAdapterProperty");
            if (irpStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(STORAGE_DESCRIPTOR_HEADER))
            {
                header->Version = 1;
                header->Size = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
                Irp->IoStatus.Information = sizeof(STORAGE_DESCRIPTOR_HEADER);
            }

            if (irpStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(STORAGE_ADAPTER_DESCRIPTOR))
            {
                adapterDescriptor = (PSTORAGE_ADAPTER_DESCRIPTOR)header;

                adapterDescriptor->MaximumTransferLength = 0x10 * PAGE_SIZE;
                adapterDescriptor->MaximumPhysicalPages = 0x10;
                adapterDescriptor->AlignmentMask = 1;
                adapterDescriptor->AdapterUsesPio = TRUE; 
                adapterDescriptor->AdapterScansDown = FALSE;
                adapterDescriptor->CommandQueueing = FALSE;
                adapterDescriptor->AcceleratedTransfer = FALSE;
                adapterDescriptor->BusType = BusTypeUnknown;//BusTypeScsi;
                adapterDescriptor->BusMajorVersion = 1;
                adapterDescriptor->BusMinorVersion = 0;

                Irp->IoStatus.Information = sizeof(STORAGE_ADAPTER_DESCRIPTOR);
            }
        }
        else if ((query->PropertyId == StorageDeviceProperty) && (query->QueryType == PropertyStandardQuery))
        {
			VScsiDiskDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__" StorageDeviceProperty");
            if (irpStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(STORAGE_DESCRIPTOR_HEADER))
            {
                header->Version = 1;
                header->Size = sizeof(STORAGE_DEVICE_DESCRIPTOR);

                Irp->IoStatus.Information = sizeof(STORAGE_DESCRIPTOR_HEADER);
            }

            if (irpStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(STORAGE_DEVICE_DESCRIPTOR))
            {
                deviceDescriptor = (PSTORAGE_DEVICE_DESCRIPTOR)header;

                deviceDescriptor->DeviceType = DIRECT_ACCESS_DEVICE;
                deviceDescriptor->DeviceTypeModifier = 0;
                deviceDescriptor->RemovableMedia = FALSE;
                deviceDescriptor->CommandQueueing = FALSE;
                deviceDescriptor->VendorIdOffset = sizeof(STORAGE_DEVICE_DESCRIPTOR);
                deviceDescriptor->ProductIdOffset = deviceDescriptor->VendorIdOffset = sizeof(STORAGE_DEVICE_DESCRIPTOR)+16;
                deviceDescriptor->ProductRevisionOffset = 0;
                deviceDescriptor->SerialNumberOffset = 0;
                deviceDescriptor->BusType = BusTypeUnknown;//BusTypeScsi;
                deviceDescriptor->RawPropertiesLength = 0;
				RtlCopyMemory((UCHAR*)header+deviceDescriptor->VendorIdOffset,L"odysys\0",20);
				RtlCopyMemory((UCHAR*)header+deviceDescriptor->ProductIdOffset,L"osm\0",12);
                Irp->IoStatus.Information = sizeof(STORAGE_DEVICE_DESCRIPTOR);
            }
        }
#ifndef WIN2K
        else if ((query->PropertyId == StorageDeviceIdProperty) && (query->QueryType == PropertyStandardQuery))
        {
			VScsiDiskDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__" StorageDeviceIdProperty");
            if (irpStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(STORAGE_DESCRIPTOR_HEADER))
            {
                header->Version = 1;
                header->Size = sizeof(STORAGE_DEVICE_ID_DESCRIPTOR);

                Irp->IoStatus.Information = sizeof(STORAGE_DESCRIPTOR_HEADER);
            }
        }
#endif

        status = STATUS_SUCCESS;
        break;
#ifndef WIN2K
    case IOCTL_STORAGE_GET_HOTPLUG_INFO:
        if (irpStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(STORAGE_HOTPLUG_INFO))
        {
            PSTORAGE_HOTPLUG_INFO hotplugInfo;

            hotplugInfo = (PSTORAGE_HOTPLUG_INFO)Irp->AssociatedIrp.SystemBuffer;

            hotplugInfo->Size = sizeof(STORAGE_HOTPLUG_INFO);
            hotplugInfo->MediaRemovable = FALSE;
            hotplugInfo->MediaHotplug = FALSE;
            hotplugInfo->DeviceHotplug = FALSE;


            status = STATUS_SUCCESS;
            Irp->IoStatus.Information = sizeof(STORAGE_HOTPLUG_INFO);
        }
        else
        {
            status = STATUS_BUFFER_TOO_SMALL;
        }
        break;
#endif
	case IOCTL_SCSI_GET_INQUIRY_DATA:
		status = STATUS_INVALID_DEVICE_REQUEST;
		VScsiDiskDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__" IOCTL_SCSI_GET_INQUIRY_DATA");
		break;
	case IOCTL_SCSI_GET_CAPABILITIES:
		status = STATUS_INVALID_DEVICE_REQUEST;
		VScsiDiskDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__" IOCTL_SCSI_GET_CAPABILITIES");
		break;
    default:
        status = STATUS_INVALID_DEVICE_REQUEST;
        break;
    }

    Irp->IoStatus.Status = status;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    VScsiDiskDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"--. IRP %p, STATUS %x", Irp, status);

    return status;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  VScsiDiskScsiInternalDeviceIoControlDispatch
//      IRP_MJ_INTERNAL_DEVICE_CONTROL handler
//
//  Arguments:
//      IN  DeviceObject
//              our PDO device object
//
//      IN  Irp
//              IRP_MJ_INTERNAL_DEVICE_CONTROL irp
//
//  Return Value:
//      Status
//
NTSTATUS VScsiDiskScsiInternalDeviceIoControlDispatch(
    IN  PDEVICE_OBJECT  DeviceObject,
    IN  PIRP            Irp
    )
{
    NTSTATUS            status;
    PIO_STACK_LOCATION  irpStack;
    PSCSI_REQUEST_BLOCK srb;
    PCDB                cdb;

    VScsiDiskDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"++. IRP %p", Irp);

    irpStack = IoGetCurrentIrpStackLocation(Irp);
    srb = irpStack->Parameters.Scsi.Srb;
    cdb = (PCDB)srb->Cdb;

    status = STATUS_SUCCESS;
    srb->SrbStatus = SRB_STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;

    switch (srb->Function)
    {
    case SRB_FUNCTION_EXECUTE_SCSI:
        VScsiDiskDebugPrint(DBG_IO, DBG_INFO, "SRB_FUNCTION_EXECUTE_SCSI");
        if (cdb->CDB6GENERIC.OperationCode == SCSIOP_READ_CAPACITY)
        {
            PREAD_CAPACITY_DATA capacity;
            ULONG               logicalBlockAddress;
            ULONG               bytesPerBlock;

            capacity = (PREAD_CAPACITY_DATA)srb->DataBuffer;

            logicalBlockAddress =VSCSI_BUFFER_SIZE/512 - 1;// 0xfffffffe;
            bytesPerBlock = 512;

            REVERSE_BYTES(&capacity->LogicalBlockAddress, &logicalBlockAddress);
            REVERSE_BYTES(&capacity->BytesPerBlock, &bytesPerBlock);
			VScsiDiskDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"read cap %x,%x\n",
				capacity->LogicalBlockAddress,capacity->BytesPerBlock);
        }
        else if (cdb->CDB6GENERIC.OperationCode == SCSIOP_TEST_UNIT_READY)
        {
			VScsiDiskDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"test unit ready...(target-lun)=(%d,%d)..zhu\n", 
					srb->TargetId,srb->Lun);
        }
        else if (cdb->CDB6GENERIC.OperationCode == SCSIOP_VERIFY)
        {
			VScsiDiskDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"verify...(target-lun)=(%d,%d)..zhu\n", 
					srb->TargetId,srb->Lun);
        }
		else if (cdb->CDB6GENERIC.OperationCode == SCSIOP_INQUIRY)
		{
			VScsiDiskDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"\t inquiry...(target-lun)=(%d,%d)..zhu\n", 
					srb->TargetId,srb->Lun);
/*			PINQUIRYDATA pInquiryData;
			VirtualScsiPortDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"\tInquiry...(target-lun)=(%d,%d)..zhu\n", 
					srb->TargetId,srb->Lun);
			if(srb->TargetId !=100)//所有的磁盘都在target100上,Lun号依次为0,1,2...
			{
				VirtualScsiPortDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"\tInquiry...(target-lun)=(%d,%d)..not supported\n", 
					srb->TargetId,srb->Lun);
                status = STATUS_INVALID_PARAMETER;
 				srb->SrbStatus = SRB_STATUS_SELECTION_TIMEOUT;
				break;
			}

			if(srb->Cdb[1] & CDB_INQUIRY_EVPD)
			{
				VirtualScsiPortDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"\tInquiry..not support evpd\n");
				status=STATUS_INVALID_PARAMETER;
				srb->SrbStatus=SRB_STATUS_ERROR;
				break;
			}

			pInquiryData = (PINQUIRYDATA)srb->DataBuffer;
			
			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;

⌨️ 快捷键说明

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