📄 charsample.c
字号:
// CharSample.c
//
// Generated by C DriverWizard 3.1.0 (Build 1722)
// Requires DDK Only
// File created on 1/23/2009
//
#include "pch.h"
#include "..\intrface.h"
#ifdef CHARSAMPLE_WMI_TRACE
#include "CharSample.tmh"
#endif
// global data
CHARSAMPLE_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;
CharSampleDebugPrint(DBG_INIT, DBG_TRACE, __FUNCTION__"++");
CharSampleDebugPrint(DBG_INIT, DBG_INFO, "Compiled at %s on %s", __TIME__, __DATE__);
#ifdef DBG
// DbgBreakPoint();
#endif
#ifdef CHARSAMPLE_WMI_TRACE
WPP_INIT_TRACING(DriverObject, RegistryPath);
#endif
status = STATUS_SUCCESS;
RtlZeroMemory(&g_Data, sizeof(CHARSAMPLE_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,
CHARSAMPLE_POOL_TAG
);
if (g_Data.RegistryPath.Buffer == NULL)
{
status = STATUS_INSUFFICIENT_RESOURCES;
CharSampleDebugPrint(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] = CharSamplePnpDispatch;
DriverObject->MajorFunction[IRP_MJ_POWER] = CharSamplePowerDispatch;
DriverObject->MajorFunction[IRP_MJ_CREATE] = CharSampleCreateDispatch;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = CharSampleCloseDispatch;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = CharSampleDeviceIoControlDispatch;
DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = CharSampleSystemControlDispatch;
DriverObject->DriverExtension->AddDevice = CharSampleAddDevice;
DriverObject->DriverUnload = CharSampleUnload;
CharSampleDebugPrint(DBG_INIT, DBG_TRACE, __FUNCTION__"--. STATUS %x", status);
return status;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// CharSampleAddDevice
// 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 CharSampleAddDevice(
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PhysicalDeviceObject
)
{
NTSTATUS status;
PDEVICE_OBJECT deviceObject;
PCHARSAMPLE_DEVICE_EXTENSION deviceExtension;
CharSampleDebugPrint(DBG_INIT, DBG_TRACE, __FUNCTION__"++: PDO %p", PhysicalDeviceObject);
// Create our function device object.
status = IoCreateDevice(
DriverObject,
sizeof (CHARSAMPLE_DEVICE_EXTENSION),
NULL, // no name
FILE_DEVICE_UNKNOWN,
FILE_DEVICE_SECURE_OPEN, // Do not use if binary intended for 9x
FALSE,
&deviceObject
);
if (!NT_SUCCESS(status))
{
CharSampleDebugPrint(DBG_INIT, DBG_ERR, __FUNCTION__"--. IoCreateDevice STATUS %x", status);
return status;
}
CharSampleDebugPrint(DBG_INIT, DBG_INFO, __FUNCTION__": Created FDO %p", deviceObject);
// Initialize the device extension.
deviceExtension = (PCHARSAMPLE_DEVICE_EXTENSION)deviceObject->DeviceExtension;
// Zero the memory
RtlZeroMemory(deviceExtension, sizeof(CHARSAMPLE_DEVICE_EXTENSION));
// save the PDO pointer
deviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;
// save our device object
deviceExtension->DeviceObject = deviceObject;
// 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
CharSampleInitializeIoLock(&deviceExtension->IoLock, deviceObject);
deviceExtension->PnpState = PnpStateNotStarted;
deviceExtension->PreviousPnpState = PnpStateNotStarted;
// 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;
}
// This flag sets the buffering method for reads and writes
// to METHOD_DIRECT. IOCTLs are handled by IO control codes
// independent of the value of this flag.
deviceObject->Flags |= DO_DIRECT_IO;
// 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)
{
CharSampleDebugPrint(DBG_INIT, DBG_ERR, __FUNCTION__"--. IoAttachDeviceToDeviceStack failed");
IoDeleteDevice(deviceObject);
return STATUS_DEVICE_REMOVED;
}
// Initialize our device's interface
status = IoRegisterDeviceInterface (
PhysicalDeviceObject,
(LPGUID)&GUID_DEVINTERFACE_CHARSAMPLE,
NULL,
&deviceExtension->InterfaceName
);
if (!NT_SUCCESS(status))
{
CharSampleDebugPrint(DBG_INIT, DBG_ERR, __FUNCTION__"--. IoRegisterDeviceInterface STATUS %x", status);
IoDetachDevice(deviceExtension->LowerDeviceObject);
IoDeleteDevice(deviceObject);
return status;
}
// 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;
CharSampleDebugPrint(DBG_INIT, DBG_TRACE, __FUNCTION__"--. CharSampleAddDevice--. STATUS %x", status);
return status;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// CharSampleStartDevice
// 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 CharSampleStartDevice(
IN PCHARSAMPLE_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;
CharSampleDebugPrint(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:
CharSampleDebugPrint(DBG_PNP, DBG_INFO, "Resource Type Port");
CharSampleDebugPrint(DBG_PNP, DBG_INFO, "Port.Start %I64x", resource->u.Port.Start.QuadPart);
CharSampleDebugPrint(DBG_PNP, DBG_INFO, "Port.Length %x", resource->u.Port.Length);
break;
case CmResourceTypeMemory:
CharSampleDebugPrint(DBG_PNP, DBG_TRACE, "Resource Type Memory");
CharSampleDebugPrint(DBG_PNP, DBG_TRACE, "Memory.Start %I64x", resource->u.Memory.Start.QuadPart);
CharSampleDebugPrint(DBG_PNP, DBG_TRACE, "Memory.Length %x", resource->u.Memory.Length);
break;
case CmResourceTypeInterrupt:
CharSampleDebugPrint(DBG_PNP, DBG_TRACE, "Resource Type Interrupt");
CharSampleDebugPrint(DBG_PNP, DBG_TRACE, "Interrupt.Level %x", resourceTrans->u.Interrupt.Level);
CharSampleDebugPrint(DBG_PNP, DBG_TRACE, "Interrupt.Vector %x", resourceTrans->u.Interrupt.Vector);
CharSampleDebugPrint(DBG_PNP, DBG_TRACE, "Interrupt.Affinity %x\n", resourceTrans->u.Interrupt.Affinity);
break;
default:
CharSampleDebugPrint(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
//*****************************************************************
//*****************************************************************
CharSampleDebugPrint(DBG_PNP, DBG_TRACE, __FUNCTION__"--. IRP %p STATUS %x", Irp, status);
return status;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// CharSampleFreeResources
// 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 CharSampleFreeResources(
IN PCHARSAMPLE_DEVICE_EXTENSION DeviceExtension
)
{
NTSTATUS status;
CharSampleDebugPrint(DBG_PNP, DBG_TRACE, __FUNCTION__"++");
CharSampleDebugPrint(DBG_PNP, DBG_TRACE, __FUNCTION__"--");
return STATUS_SUCCESS;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// CharSampleCreateDispatch
// 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 CharSampleCreateDispatch(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PCHARSAMPLE_DEVICE_EXTENSION deviceExtension;
NTSTATUS status;
CharSampleDebugPrint(DBG_CREATECLOSE, DBG_TRACE, __FUNCTION__": IRP %p", Irp);
deviceExtension = (PCHARSAMPLE_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
if (!CharSampleAcquireRemoveLock(deviceExtension))
{
status = STATUS_NO_SUCH_DEVICE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -