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

📄 pdo.c

📁 虚拟Scsi Disk源程序 版权归原作者
💻 C
📖 第 1 页 / 共 3 页
字号:
// pdo.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 "pdo.tmh"
#endif

///////////////////////////////////////////////////////////////////////////////////////////////////
//  VScsiDiskPdoPnpDispatch
//      IRP_MJ_PNP dispatch handler for PDO.
//
//  Arguments:
//      IN  DeviceObject
//              PDO
//
//      IN  Irp
//              IRP_MJ_PNP Irp
//
//  Return Value:
//      NT status code.
//
NTSTATUS VScsiDiskPdoPnpDispatch(
    IN PDEVICE_OBJECT   DeviceObject,
    IN PIRP             Irp
    )
{
    PVSCSIDISK_PDO_DEVICE_EXTENSION   pdoExtension;
    PVSCSIDISK_DEVICE_EXTENSION       fdoExtension;
    NTSTATUS                        status;
    PIO_STACK_LOCATION              irpStack;
    POWER_STATE                     powerState;

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

    VScsiDiskDumpIrp(Irp);

    pdoExtension = (PVSCSIDISK_PDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;

    // Get our current IRP stack location
    irpStack = IoGetCurrentIrpStackLocation(Irp);

    switch (irpStack->MinorFunction)
    {
    case IRP_MN_START_DEVICE:
        // IRP_MN_START_DEVICE is an implicit power up
        pdoExtension->DevicePowerState = PowerDeviceD0;
        powerState.DeviceState = PowerDeviceD0;
        PoSetPowerState(pdoExtension->DeviceObject, DevicePowerState, powerState);

        // update our pnp state
        pdoExtension->PnpState = PnpStateStarted;
        status = STATUS_SUCCESS;
        break;

    case IRP_MN_QUERY_STOP_DEVICE:
        // Update our pnp state
        pdoExtension->PreviousPnpState = pdoExtension->PnpState;
        pdoExtension->PnpState = PnpStateStopPending;
        status = STATUS_SUCCESS;
        break;

    case IRP_MN_CANCEL_STOP_DEVICE:
        if (pdoExtension->PnpState == PnpStateStopPending) 
        {
            // restore previous pnp state
            pdoExtension->PnpState = pdoExtension->PreviousPnpState;
        }

        status = STATUS_SUCCESS;
        break;

    case IRP_MN_STOP_DEVICE:
        // Mark the device as stopped.
        pdoExtension->PnpState = PnpStateStopped;
        status = STATUS_SUCCESS;
        break;

    case IRP_MN_QUERY_REMOVE_DEVICE:
        // Update our pnp state
        pdoExtension->PreviousPnpState = pdoExtension->PnpState;
        pdoExtension->PnpState = PnpStateRemovePending;
        status = STATUS_SUCCESS;
        break;

    case IRP_MN_CANCEL_REMOVE_DEVICE:
        if (pdoExtension->PnpState == PnpStateRemovePending) 
        {
            // restore previous pnp state
            pdoExtension->PnpState = pdoExtension->PreviousPnpState;
        }

        status = STATUS_SUCCESS;
        break;

    case IRP_MN_SURPRISE_REMOVAL:
        pdoExtension->PnpState = PnpStateSurpriseRemoved;
        status = STATUS_SUCCESS;
        break;

    case IRP_MN_REMOVE_DEVICE:
        if (pdoExtension->DeleteOnRemove)
        {
            pdoExtension->PnpState = PnpStateRemoved;

            if (pdoExtension->ParentDeviceObject)
            {
                fdoExtension = 
                    (PVSCSIDISK_DEVICE_EXTENSION)pdoExtension->ParentDeviceObject->DeviceExtension;

                ExAcquireFastMutex(&fdoExtension->PdoListLock);
                RemoveEntryList(&pdoExtension->PdoListEntry);
                ExReleaseFastMutex(&fdoExtension->PdoListLock);
            }

            //*****************************************************************
            //*****************************************************************
            // TODO: Free PDO resources
            //*****************************************************************
            //*****************************************************************
            if (pdoExtension->HardwareId != NULL)
            {
                ExFreePool(pdoExtension->HardwareId);
                pdoExtension->HardwareId = NULL;
            }

            IoDeleteDevice(DeviceObject);
        }
        else if (pdoExtension->IsExist)
        {
            pdoExtension->PnpState = PnpStateNotStarted;
        }

        status = STATUS_SUCCESS;
        break;

    case IRP_MN_QUERY_CAPABILITIES:
        status = VScsiDiskPdoQueryCapabilities(pdoExtension, Irp);
        break;

    case IRP_MN_QUERY_ID:
        status = VScsiDiskPdoQueryId(pdoExtension, Irp);
//		Irp->IoStatus.Information=0;
//		status=STATUS_SUCCESS;
        break;

    case IRP_MN_QUERY_DEVICE_RELATIONS:
        status = VScsiDiskPdoQueryDeviceRelations(pdoExtension, Irp);
        break;

    case IRP_MN_QUERY_DEVICE_TEXT:
        status = VScsiDiskPdoQueryDeviceText(pdoExtension, Irp);
        break;

    case IRP_MN_QUERY_RESOURCES:
        status = VScsiDiskPdoQueryResources(pdoExtension, Irp);
        break;

    case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
        status = VScsiDiskPdoQueryResourceRequirements(pdoExtension, Irp);
        break;

    case IRP_MN_QUERY_BUS_INFORMATION:
        status = VScsiDiskPdoQueryBusInformation(pdoExtension, Irp);
        break;

    case IRP_MN_DEVICE_USAGE_NOTIFICATION:
        status = VScsiDiskPdoDeviceUsageNotification(pdoExtension, Irp);
        break;

    case IRP_MN_EJECT:
        status = VScsiDiskPdoEject(pdoExtension, Irp);
        break;

    case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
        status = VScsiDiskPdoFilterResourceRequirements(pdoExtension, Irp);
        break;

    case IRP_MN_QUERY_PNP_DEVICE_STATE:
        status = VScsiDiskPdoPnpDeviceState(pdoExtension, Irp);
        break;

    case IRP_MN_READ_CONFIG:
        status = VScsiDiskPdoReadConfig(pdoExtension, Irp);
        break;

    case IRP_MN_WRITE_CONFIG:
        status = VScsiDiskPdoWriteConfig(pdoExtension, Irp);
        break;

    case IRP_MN_SET_LOCK:
        status = VScsiDiskPdoSetLock(pdoExtension, Irp);
        break;

    default:
        status = Irp->IoStatus.Status;
        break;
    }

    if (status != STATUS_PENDING)
    {
        Irp->IoStatus.Status = status;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
    }

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

    return status;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  VScsiDiskPdoQueryCapabilities
//      IRP_MN_QUERY_CAPABILITIES handler.
//
//  Arguments:
//      IN  PdoExtension
//              PDO device extension
//
//      IN  Irp
//              IRP_MN_QUERY_CAPABILITIES Irp
//
//  Return Value:
//      NT status code.
//
NTSTATUS VScsiDiskPdoQueryCapabilities(
    IN  PVSCSIDISK_PDO_DEVICE_EXTENSION   PdoExtension,
    IN  PIRP                                    Irp
    )
{
    NTSTATUS    status;

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

    status = VScsiDiskPdoForwardRequestToParent(PdoExtension, Irp, FALSE);

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

    return status;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  VScsiDiskPdoQueryId
//      IRP_MN_QUERY_ID handler.
//
//  Arguments:
//      IN  PdoExtension
//              PDO device extension
//
//      IN  Irp
//              IRP_MN_QUERY_ID Irp
//
//  Return Value:
//      NT status code.
//
NTSTATUS VScsiDiskPdoQueryId(
    IN  PVSCSIDISK_PDO_DEVICE_EXTENSION   PdoExtension,
    IN  PIRP                                    Irp
    )
{
    NTSTATUS            status;
    PIO_STACK_LOCATION  irpStack;
    PWCHAR              pInformation;
    ULONG               size;

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

    irpStack = IoGetCurrentIrpStackLocation(Irp);

    switch (irpStack->Parameters.QueryId.IdType)
    {
    case BusQueryDeviceID:
        pInformation = PdoExtension->HardwareId;

        // find the size of HardwareId multi string
        while (*(pInformation++)) 
            while (*(pInformation++));

        size = (ULONG)(pInformation - PdoExtension->HardwareId)*sizeof(WCHAR);

        pInformation = (PWCHAR)ExAllocatePoolWithTag(PagedPool, size, VSCSIDISK_POOL_TAG);
        if (pInformation != NULL)
        {
            RtlCopyMemory(pInformation, PdoExtension->HardwareId, size);
            Irp->IoStatus.Information = (ULONG_PTR)pInformation;
            status = STATUS_SUCCESS;
        }
        else
        {
            status = STATUS_INSUFFICIENT_RESOURCES;
        }

        break;

    case BusQueryInstanceID:

        size = 9 * sizeof(WCHAR);

        pInformation = (PWCHAR)ExAllocatePoolWithTag(PagedPool, size, VSCSIDISK_POOL_TAG);
        if (pInformation != NULL)
        {
            RtlZeroMemory(pInformation, size);
            RtlStringCchPrintfW(pInformation, size, L"%04d", PdoExtension->DeviceId);
            Irp->IoStatus.Information = (ULONG_PTR)pInformation;
            status = STATUS_SUCCESS;
        }
        else
        {
            status = STATUS_INSUFFICIENT_RESOURCES;
        }
        break;

    case BusQueryHardwareIDs:
        pInformation = PdoExtension->HardwareId;

        // find the size of HardwareId multi string
        while (*(pInformation++)) 
            while (*(pInformation++));

        size = (ULONG)(pInformation - PdoExtension->HardwareId)*sizeof(WCHAR);

        pInformation = (PWCHAR)ExAllocatePoolWithTag(PagedPool, size, VSCSIDISK_POOL_TAG);
        if (pInformation != NULL)
        {
            RtlCopyMemory(pInformation, PdoExtension->HardwareId, size);
            Irp->IoStatus.Information = (ULONG_PTR)pInformation;
            status = STATUS_SUCCESS;
        }
        else
        {
            status = STATUS_INSUFFICIENT_RESOURCES;
        }

        break;

    case BusQueryCompatibleIDs:
        status = Irp->IoStatus.Status;
        break;

    default:
        status = Irp->IoStatus.Status;
        break;
    }

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

    return status;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  VScsiDiskPdoQueryDeviceRelations
//      IRP_MN_QUERY_DEVICE_RELATIONS handler.
//
//  Arguments:
//      IN  PdoExtension
//              PDO device extension
//
//      IN  Irp
//              IRP_MN_QUERY_DEVICE_RELATIONS Irp
//
//  Return Value:
//      NT status code.
//
NTSTATUS VScsiDiskPdoQueryDeviceRelations(
    IN  PVSCSIDISK_PDO_DEVICE_EXTENSION   PdoExtension,
    IN  PIRP                                    Irp
    )
{
    NTSTATUS            status;
    PIO_STACK_LOCATION  irpStack;
    PDEVICE_RELATIONS   deviceRelations;

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

    irpStack = IoGetCurrentIrpStackLocation(Irp);

    switch (irpStack->Parameters.QueryDeviceRelations.Type)
    {
    case TargetDeviceRelation:
        deviceRelations = (PDEVICE_RELATIONS)ExAllocatePoolWithTag(
                                                PagedPool,
                                                sizeof(DEVICE_RELATIONS),
                                                VSCSIDISK_POOL_TAG
                                                );

        if (deviceRelations != NULL)
        {
            deviceRelations->Count = 1;
            deviceRelations->Objects[0] = PdoExtension->DeviceObject;
            ObReferenceObject(PdoExtension->DeviceObject);

            status = STATUS_SUCCESS;
            Irp->IoStatus.Information = (ULONG_PTR)deviceRelations;
        }
        else
        {
            status = STATUS_INSUFFICIENT_RESOURCES;
        }
        break;

    case EjectionRelations:
        status = Irp->IoStatus.Status;
        break;

    case RemovalRelations:
        status = Irp->IoStatus.Status;
        break;

    default:
        status = Irp->IoStatus.Status;
        break;
    }

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

    return status;
}

///////////////////////////////////////////////////////////////////////////////////////////////////
//  VScsiDiskPdoQueryDeviceText
//      IRP_MN_QUERY_DEVICE_TEXT handler.
//
//  Arguments:
//      IN  PdoExtension
//              PDO device extension
//
//      IN  Irp
//              IRP_MN_QUERY_DEVICE_TEXT Irp
//
//  Return Value:
//      NT status code.
//
NTSTATUS VScsiDiskPdoQueryDeviceText(
    IN  PVSCSIDISK_PDO_DEVICE_EXTENSION   PdoExtension,
    IN  PIRP                                    Irp
    )
{
    NTSTATUS            status;
    PIO_STACK_LOCATION  irpStack;
    ULONG               size;
    PWCHAR              pInformation;

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

    irpStack = IoGetCurrentIrpStackLocation(Irp);

    switch (irpStack->Parameters.QueryDeviceText.DeviceTextType)
    {
    case DeviceTextDescription:
        if (Irp->IoStatus.Information == (ULONG_PTR)NULL)
        {
            size = (ULONG)(wcslen(L"OSM VSD Device PDO") + 9)*sizeof(WCHAR);

            pInformation = (PWCHAR)ExAllocatePoolWithTag(
                                    PagedPool,
                                    size,
                                    VSCSIDISK_POOL_TAG
                                    );

            if (pInformation != NULL)
            {
                RtlZeroMemory(pInformation, size);

                RtlStringCchPrintfW(
                    pInformation, 
                    size, 
                    L"%ws%04d", L"OSM Virtual Scsi Disk ", PdoExtension->DeviceId
                    );

                Irp->IoStatus.Information = (ULONG_PTR)pInformation;
                status = STATUS_SUCCESS;
            }

⌨️ 快捷键说明

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