📄 vscsidisk.c
字号:
// VScsiDisk.c
//
// Generated by C DriverWizard 3.2.0 (Build 2485)
// Requires DDK Only
// File created on 5/18/2005
//
#include "pch.h"
#include "..\intrface.h"
#ifdef VSCSIDISK_WMI_TRACE
#include "VScsiDisk.tmh"
#endif
// global data
VSCSIDISK_DATA g_Data;
///////////////////////////////////////////////////////////////////////////////////////////////////
// DriverEntry
// Installable driver initialization entry point.
// This entry point is called directly by the I/O system.
//
// Arguments:
// IN DriverObject
// pointer to the driver object
//
// IN RegistryPath
// pointer to a unicode string representing the path,
// to driver-specific key in the registry.
//
// Return Value:
// Status
//
NTSTATUS DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
NTSTATUS status;
VScsiDiskDebugPrint(DBG_INIT, DBG_TRACE, __FUNCTION__"++");
VScsiDiskDebugPrint(DBG_INIT, DBG_INFO, "Compiled at %s on %s", __TIME__, __DATE__);
#ifdef DBG
// DbgBreakPoint();
#endif
#ifdef VSCSIDISK_WMI_TRACE
WPP_INIT_TRACING(DriverObject, RegistryPath);
#endif
status = STATUS_SUCCESS;
RtlZeroMemory(&g_Data, sizeof(VSCSIDISK_DATA));
// save registry path for wmi
g_Data.RegistryPath.Length = RegistryPath->Length;
g_Data.RegistryPath.MaximumLength = RegistryPath->Length + sizeof(UNICODE_NULL);
g_Data.RegistryPath.Buffer = (PWCHAR)ExAllocatePoolWithTag(
PagedPool,
g_Data.RegistryPath.MaximumLength,
VSCSIDISK_POOL_TAG
);
if (g_Data.RegistryPath.Buffer == NULL)
{
status = STATUS_INSUFFICIENT_RESOURCES;
VScsiDiskDebugPrint(DBG_INIT, DBG_ERR, __FUNCTION__": Failed to allocate memory for RegistryPath");
return status;
}
RtlCopyUnicodeString(&g_Data.RegistryPath, RegistryPath);
// detect current operating system
if (IoIsWdmVersionAvailable(1, 0x30))
{
g_Data.WdmVersion = 0x0130;
}
else if (IoIsWdmVersionAvailable(1, 0x20))
{
g_Data.WdmVersion = 0x0120;
}
else if (IoIsWdmVersionAvailable(1, 0x10))
{
g_Data.WdmVersion = 0x0110;
}
else if (IoIsWdmVersionAvailable(1, 0x05))
{
g_Data.WdmVersion = 0x0105;
}
else
{
g_Data.WdmVersion = 0x0100;
}
// setup our dispatch function table in the driver object
DriverObject->MajorFunction[IRP_MJ_PNP] = VScsiDiskPnpDispatch;
DriverObject->MajorFunction[IRP_MJ_POWER] = VScsiDiskPowerDispatch;
DriverObject->MajorFunction[IRP_MJ_CREATE] = VScsiDiskCreateDispatch;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = VScsiDiskCloseDispatch;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = VScsiDiskDeviceIoControlDispatch;
DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = VScsiDiskInternalDeviceIoControlDispatch;
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = VScsiDiskCleanupDispatch;
DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = VScsiDiskSystemControlDispatch;
DriverObject->DriverExtension->AddDevice = VScsiDiskAddDevice;
DriverObject->DriverUnload = VScsiDiskUnload;
VScsiDiskDebugPrint(DBG_INIT, DBG_TRACE, __FUNCTION__"--. STATUS %x", status);
return status;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// VScsiDiskAddDevice
// The PnP manager new device callback
//
// Arguments:
// IN DeviceObject
// pointer to a device object.
//
// IN PhysicalDeviceObject
// pointer to a device object created by the
// underlying bus driver.
//
// Return Value:
// Status
//
NTSTATUS VScsiDiskAddDevice(
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PhysicalDeviceObject
)
{
NTSTATUS status;
PDEVICE_OBJECT deviceObject;
PVSCSIDISK_DEVICE_EXTENSION deviceExtension;
POWER_STATE powerState;
UNICODE_STRING busFdoName;
VScsiDiskDebugPrint(DBG_INIT, DBG_TRACE, __FUNCTION__"++: PDO %p", PhysicalDeviceObject);
// Create our function device object.
RtlInitUnicodeString(&busFdoName,BUS_FDO_NAME);
status = IoCreateDevice(
DriverObject,
sizeof (VSCSIDISK_DEVICE_EXTENSION),
&busFdoName, // device name
// FILE_DEVICE_UNKNOWN,
FILE_DEVICE_BUS_EXTENDER,//modified by zhu,2005-05-18
FILE_DEVICE_SECURE_OPEN, // Do not use if binary intended for 9x
FALSE,
&deviceObject
);
if (!NT_SUCCESS(status))
{
VScsiDiskDebugPrint(DBG_INIT, DBG_ERR, __FUNCTION__"--. IoCreateDevice STATUS %x", status);
return status;
}
VScsiDiskDebugPrint(DBG_INIT, DBG_INFO, __FUNCTION__": Created FDO %p", deviceObject);
// Initialize the device extension.
deviceExtension = (PVSCSIDISK_DEVICE_EXTENSION)deviceObject->DeviceExtension;
// Zero the memory
RtlZeroMemory(deviceExtension, sizeof(VSCSIDISK_DEVICE_EXTENSION));
deviceExtension->IsPdo = FALSE;
// initialize list of PDO's
ExInitializeFastMutex(&deviceExtension->PdoListLock);
InitializeListHead(&deviceExtension->PdoListHead);
// save the PDO pointer
deviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;
// save our device object
deviceExtension->DeviceObject = deviceObject;
// Initialize the powering down flag
deviceExtension->bPowerStop = FALSE;
// set RemoveCount to 1. Transition to zero
// means IRP_MN_REMOVE_DEVICE was received
deviceExtension->RemoveCount = 1;
// Initialize Remove event
KeInitializeEvent(&deviceExtension->RemoveEvent, NotificationEvent, FALSE);
// initialize io lock
VScsiDiskInitializeIoLock(&deviceExtension->IoLock, deviceObject);
deviceExtension->PnpState = PnpStateNotStarted;
deviceExtension->PreviousPnpState = PnpStateNotStarted;
// allocate WorkItem for power processing
deviceExtension->PowerWorkItem = IoAllocateWorkItem(deviceExtension->DeviceObject);
if (deviceExtension->PowerWorkItem == NULL)
{
VScsiDiskDebugPrint(DBG_INIT, DBG_ERR, __FUNCTION__"--. Failed to allocated PowerWorkItem");
IoDeleteDevice(deviceObject);
return STATUS_INSUFFICIENT_RESOURCES;
}
// Initialize the device object flags
// All WDM drivers are supposed to set this flag. Devices
// requiring a large amount of current at statup set the
// DO_POWER_INRUSH flag instead. These flags are mutually
// exclusive.
if (PhysicalDeviceObject->Flags & DO_POWER_PAGABLE)
{
deviceObject->Flags |= DO_POWER_PAGABLE;
}
// Typically, (almost always) the function driver for a device is the
// power policy owner for that device. In some cases
// another driver or system component may assume this role.
// Set the initial device power state of the device to powered down.
deviceExtension->DevicePowerState = PowerDeviceD3;
powerState.DeviceState = deviceExtension->DevicePowerState;
// the initial system power state must be working or we wouldn't be here.
deviceExtension->SystemPowerState = PowerSystemWorking;
// Call PoSetPowerState to notify the power manager of our initial power state.
PoSetPowerState(deviceObject, DevicePowerState, powerState);
// Attach our device to the device stack and get the device object to
// which we send down IRPs to.
deviceExtension->LowerDeviceObject = IoAttachDeviceToDeviceStack(
deviceObject,
PhysicalDeviceObject
);
if (deviceExtension->LowerDeviceObject == NULL)
{
VScsiDiskDebugPrint(DBG_INIT, DBG_ERR, __FUNCTION__"--. IoAttachDeviceToDeviceStack failed");
IoFreeWorkItem(deviceExtension->PowerWorkItem);
IoDeleteDevice(deviceObject);
return STATUS_DEVICE_REMOVED;
}
// increment device instance count
++g_Data.InstanceCount;
// We are all done, so we need to clear the
// DO_DEVICE_INITIALIZING flag. This must be our
// last action in AddDevice
deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
VScsiDiskDebugPrint(DBG_INIT, DBG_TRACE, __FUNCTION__"--. VScsiDiskAddDevice--. STATUS %x", status);
return status;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// VScsiDiskStartDevice
// Start device handler, sets up resources
//
// Arguments:
// IN DeviceExtension
// our device extension
//
// IN Irp
// pointer to the Start IRP
//
// Return Value:
// NT status code
//
NTSTATUS VScsiDiskStartDevice(
IN PVSCSIDISK_DEVICE_EXTENSION DeviceExtension,
IN PIRP Irp
)
{
NTSTATUS status = STATUS_SUCCESS;
PCM_PARTIAL_RESOURCE_DESCRIPTOR resource;
PCM_PARTIAL_RESOURCE_DESCRIPTOR resourceTrans;
PCM_PARTIAL_RESOURCE_LIST partialResourceList;
PCM_PARTIAL_RESOURCE_LIST partialResourceListTranslated;
PIO_STACK_LOCATION irpStack;
POWER_STATE powerState;
ULONG ii;
VScsiDiskDebugPrint(DBG_PNP, DBG_TRACE, __FUNCTION__"++. IRP %p", Irp);
// Get our current IRP stack location
irpStack = IoGetCurrentIrpStackLocation(Irp);
// Do whatever initialization needed when starting the device:
// gather information about it, update the registry, etc.
// At this point, the lower level drivers completed the IRP
if ((irpStack->Parameters.StartDevice.AllocatedResources != NULL) &&
(irpStack->Parameters.StartDevice.AllocatedResourcesTranslated != NULL))
{
// Parameters.StartDevice.AllocatedResources points to a
// CM_RESOURCE_LIST describing the hardware resources that
// the PnP Manager assigned to the device. This list contains
// the resources in raw form. Use the raw resources to program
// the device.
partialResourceList =
&irpStack->Parameters.StartDevice.AllocatedResources->List[0].PartialResourceList;
resource = &partialResourceList->PartialDescriptors[0];
// Parameters.StartDevice.AllocatedResourcesTranslated points
// to a CM_RESOURCE_LIST describing the hardware resources that
// the PnP Manager assigned to the device. This list contains
// the resources in translated form. Use the translated resources
// to connect the interrupt vector, map I/O space, and map memory.
partialResourceListTranslated =
&irpStack->Parameters.StartDevice.AllocatedResourcesTranslated->List[0].PartialResourceList;
resourceTrans = &partialResourceListTranslated->PartialDescriptors[0];
// search the resources
for (ii = 0;
ii < partialResourceList->Count;
++ii, ++resource, ++resourceTrans)
{
switch (resource->Type)
{
case CmResourceTypePort:
VScsiDiskDebugPrint(DBG_PNP, DBG_INFO, "Resource Type Port");
VScsiDiskDebugPrint(DBG_PNP, DBG_INFO, "Port.Start %I64x", resource->u.Port.Start.QuadPart);
VScsiDiskDebugPrint(DBG_PNP, DBG_INFO, "Port.Length %x", resource->u.Port.Length);
break;
case CmResourceTypeMemory:
VScsiDiskDebugPrint(DBG_PNP, DBG_TRACE, "Resource Type Memory");
VScsiDiskDebugPrint(DBG_PNP, DBG_TRACE, "Memory.Start %I64x", resource->u.Memory.Start.QuadPart);
VScsiDiskDebugPrint(DBG_PNP, DBG_TRACE, "Memory.Length %x", resource->u.Memory.Length);
break;
case CmResourceTypeInterrupt:
VScsiDiskDebugPrint(DBG_PNP, DBG_TRACE, "Resource Type Interrupt");
VScsiDiskDebugPrint(DBG_PNP, DBG_TRACE, "Interrupt.Level %x", resourceTrans->u.Interrupt.Level);
VScsiDiskDebugPrint(DBG_PNP, DBG_TRACE, "Interrupt.Vector %x", resourceTrans->u.Interrupt.Vector);
VScsiDiskDebugPrint(DBG_PNP, DBG_TRACE, "Interrupt.Affinity %x\n", resourceTrans->u.Interrupt.Affinity);
break;
default:
VScsiDiskDebugPrint(DBG_PNP, DBG_TRACE, "Unknown Resource Type %x", resourceTrans->Type);
break;
}
}
}
//*****************************************************************
//*****************************************************************
// TODO: check that all required resources have been allocated
//*****************************************************************
//*****************************************************************
//*****************************************************************
//*****************************************************************
// TODO: allocate and initialize dma and shared memory resources
//*****************************************************************
//*****************************************************************
//*****************************************************************
//*****************************************************************
// TODO: Reset and initialize your hardware
//*****************************************************************
//*****************************************************************
//*****************************************************************
//*****************************************************************
// TODO: enable interrupts
//*****************************************************************
//*****************************************************************
VScsiDiskDebugPrint(DBG_PNP, DBG_TRACE, __FUNCTION__"--. IRP %p STATUS %x", Irp, status);
return status;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// VScsiDiskFreeResources
// This routine returns all the resources acquired during
// device startup. Here we disconnect from any interrupt,
// unmap any I/O ports that are mapped in StartDevice, and
// disable any device interfaces or symbolic links.
// Before disconnecting an interrupt, be sure the device can
// no longer generate interrupts.
//
// Arguments:
// IN DeviceExtension
// our device extension
//
// Return Value:
// NT status code
//
NTSTATUS VScsiDiskFreeResources(
IN PVSCSIDISK_DEVICE_EXTENSION DeviceExtension
)
{
NTSTATUS status;
VScsiDiskDebugPrint(DBG_PNP, DBG_TRACE, __FUNCTION__"++");
VScsiDiskDebugPrint(DBG_PNP, DBG_TRACE, __FUNCTION__"--");
return STATUS_SUCCESS;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// VScsiDiskCreateDispatch
// Dispatch routine for IRP_MJ_CREATE requests.
//
// Arguments:
// IN DeviceObject
// pointer to the device object for our device
//
// IN Irp
// the create IRP
//
// Return Value:
// NT status code.
//
NTSTATUS VScsiDiskCreateDispatch(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PVSCSIDISK_DEVICE_EXTENSION deviceExtension;
NTSTATUS status;
VScsiDiskDebugPrint(DBG_CREATECLOSE, DBG_TRACE, __FUNCTION__": IRP %p", Irp);
// check if request is directed to PDO
if (VScsiDiskIsPdo(DeviceObject))
{
status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
VScsiDiskDebugPrint(DBG_CREATECLOSE, DBG_WARN, __FUNCTION__"--. IRP %p, STATUS %x", Irp, status);
return status;
}
deviceExtension = (PVSCSIDISK_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
if (!VScsiDiskAcquireRemoveLock(deviceExtension))
{
status = STATUS_NO_SUCH_DEVICE;
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
VScsiDiskDebugPrint(DBG_CREATECLOSE, DBG_WARN, __FUNCTION__"$$--. IRP %p, STATUS %x", Irp, status);
return status;
}
// increment open count
InterlockedIncrement(&deviceExtension->OpenHandleCount);
status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
VScsiDiskReleaseRemoveLock(deviceExtension);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -