?? hellowdm.cpp
字號:
//
//Created by
//Tsinghua University E.E. Tanzhangxi(xtan) 1999.9.7
//
#define INITGUID // define GUID_HELLOWDM
#include "hellowdm.h"
#include "hellowdmioctl.h"
NTSTATUS _stdcall DriverEntry(IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath)
{ // DriverEntry
DbgPrint("Entering DeviceEntry.\n");
DriverObject->DriverUnload = DriverUnload;
DriverObject->DriverExtension->AddDevice = AddDevice;
DriverObject->MajorFunction[IRP_MJ_CREATE] = RequestCreate;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = RequestClose;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = RequestControl;
DriverObject->MajorFunction[IRP_MJ_PNP] = RequestPnp;
DriverObject->DriverStartIo = StartIo;
return STATUS_SUCCESS;
} // DriverEntry
NTSTATUS RequestPnp(IN PDEVICE_OBJECT fdo, IN PIRP Irp)
{ // RequestPnp
if (!LockDevice(fdo)) return CompleteRequest(Irp, STATUS_DELETE_PENDING, 0);
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
static NTSTATUS (*fcntab[])(IN PDEVICE_OBJECT fdo, IN PIRP Irp) = {
HandleStartDevice, // IRP_MN_START_DEVICE
DefaultPnpHandler, // IRP_MN_QUERY_REMOVE_DEVICE
HandleRemoveDevice, // IRP_MN_REMOVE_DEVICE
DefaultPnpHandler, // IRP_MN_CANCEL_REMOVE_DEVICE
HandleStopDevice, // IRP_MN_STOP_DEVICE
DefaultPnpHandler, // IRP_MN_QUERY_STOP_DEVICE
DefaultPnpHandler, // IRP_MN_CANCEL_STOP_DEVICE
DefaultPnpHandler, // IRP_MN_QUERY_DEVICE_RELATIONS
DefaultPnpHandler, // IRP_MN_QUERY_INTERFACE
DefaultPnpHandler, // IRP_MN_QUERY_CAPABILITIES
DefaultPnpHandler, // IRP_MN_QUERY_RESOURCES
DefaultPnpHandler, // IRP_MN_QUERY_RESOURCE_REQUIREMENTS
DefaultPnpHandler, // IRP_MN_QUERY_DEVICE_TEXT
DefaultPnpHandler, //
DefaultPnpHandler, //
DefaultPnpHandler, // IRP_MN_READ_CONFIG
DefaultPnpHandler, // IRP_MN_WRITE_CONFIG
DefaultPnpHandler, // IRP_MN_EJECT
DefaultPnpHandler, // IRP_MN_SET_LOCK
DefaultPnpHandler, // IRP_MN_QUERY_ID
DefaultPnpHandler, // IRP_MN_PNP_DEVICE_STATE
};
ULONG fcn = stack->MinorFunction;
NTSTATUS status;
if (fcn >= arraysize(fcntab))
{ // unknown function
status = DefaultPnpHandler(fdo, Irp);
UnlockDevice(fdo);
return status;
} // unknown function
status = (*fcntab[fcn])(fdo, Irp);
if (fcn != IRP_MN_REMOVE_DEVICE)
UnlockDevice(fdo);
return status;
} // RequestPnp
VOID DriverUnload(IN PDRIVER_OBJECT DriverObject)
{ // DriverUnload
DbgPrint("Hellowdm - Entering DriverUnload: DriverObject %8.8lX\n", DriverObject);
} // DriverUnload
NTSTATUS DefaultPnpHandler(IN PDEVICE_OBJECT fdo, IN PIRP Irp)
{ // DefaultPnpHandler
IoSkipCurrentIrpStackLocation(Irp);
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
return IoCallDriver(pdx->LowerDeviceObject, Irp);
} // DefaultPnpHandler
VOID RemoveDevice(IN PDEVICE_OBJECT fdo)
{ // RemoveDevice
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
IoSetDeviceInterfaceState(&pdx->ifname, FALSE);
if (pdx->ifname.Buffer)
ExFreePool((PVOID) pdx->ifname.Buffer);
if (pdx->LowerDeviceObject)
IoDetachDevice(pdx->LowerDeviceObject);
IoDeleteDevice(fdo);
} // RemoveDevice
NTSTATUS HandleRemoveDevice(IN PDEVICE_OBJECT fdo, IN PIRP Irp)
{ // HandleRemoveDevice
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
pdx->removing = TRUE;
UnlockDevice(pdx);
UnlockDevice(pdx);
KeWaitForSingleObject(&pdx->evRemove, Executive, KernelMode, FALSE, NULL);
StopDevice(fdo);
NTSTATUS status = DefaultPnpHandler(fdo, Irp);
RemoveDevice(fdo);
return status;
} // HandleRemoveDevice
BOOLEAN LockDevice(PDEVICE_EXTENSION pdx)
{ // LockDevice
LONG usage = InterlockedIncrement(&pdx->usage);
if (pdx->removing)
{ // removing device
if (InterlockedDecrement(&pdx->usage) == 0)
KeSetEvent(&pdx->evRemove, 0, FALSE);
return FALSE;
} // removing device
return TRUE;
} // LockDevice
NTSTATUS ForwardAndWait(IN PDEVICE_OBJECT fdo, IN PIRP Irp)
{ // ForwardAndWait
KEVENT event;
KeInitializeEvent(&event, NotificationEvent, FALSE);
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE)
OnRequestComplete, (PVOID) &event, TRUE, TRUE, TRUE);
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
NTSTATUS status = IoCallDriver(pdx->LowerDeviceObject, Irp);
if (status == STATUS_PENDING)
{ // wait for completion
KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);
status = Irp->IoStatus.Status;
} // wait for completion
return status;
} // ForwardAndWait
BOOLEAN LockDevice(IN PDEVICE_OBJECT fdo)
{
return LockDevice((PDEVICE_EXTENSION) fdo->DeviceExtension);
}
NTSTATUS StartDevice(PDEVICE_OBJECT fdo, PCM_PARTIAL_RESOURCE_LIST list)
{ // StartDevice
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
pdx->started = TRUE;
return STATUS_SUCCESS;
} // StartDevice
NTSTATUS HandleStartDevice(IN PDEVICE_OBJECT fdo, IN PIRP Irp)
{ // HandleStartDevice
NTSTATUS status = ForwardAndWait(fdo, Irp);
if (!NT_SUCCESS(status))
return CompleteRequest(Irp, status, Irp->IoStatus.Information);
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
status = StartDevice(fdo, &stack->Parameters.StartDevice.
AllocatedResourcesTranslated->List[0].PartialResourceList);
return CompleteRequest(Irp, status, 0);
} // HandleStartDevice
NTSTATUS HandleStopDevice(IN PDEVICE_OBJECT fdo, IN PIRP Irp)
{ // HandleStopDevice
NTSTATUS status = DefaultPnpHandler(fdo, Irp);
StopDevice(fdo);
return status;
} // HandleStopDevice
NTSTATUS AddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT pdo)
{ // AddDevice
NTSTATUS status;
PDEVICE_OBJECT fdo;
status = IoCreateDevice(DriverObject, sizeof(DEVICE_EXTENSION), NULL,
FILE_DEVICE_UNKNOWN, 0, FALSE, &fdo);
if (!NT_SUCCESS(status))
return status;
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) (fdo->DeviceExtension);
pdx->DeviceObject = fdo;
pdx->usage = 1; // locked until RemoveDevice
KeInitializeEvent(&pdx->evRemove, NotificationEvent, FALSE);
status = IoRegisterDeviceInterface(pdo, &GUID_HELLOWDM, NULL,
&pdx->ifname);
if (!NT_SUCCESS(status))
{ // unable to register interface
IoDeleteDevice(fdo);
return status;
} // unable to register interface
IoSetDeviceInterfaceState(&pdx->ifname, TRUE);
pdx->LowerDeviceObject = IoAttachDeviceToDeviceStack(fdo, pdo);
fdo->Flags &= ~DO_DEVICE_INITIALIZING;
fdo->Flags |= DO_BUFFERED_IO;
pdx->power = PowerDeviceD0; // device starts in full power state
pdx->idle = PoRegisterDeviceForIdleDetection(pdo,
SIMPLE_IDLE_CONSERVATION, SIMPLE_IDLE_PERFORMANCE, PowerDeviceD3);
return STATUS_SUCCESS;
} // AddDevice
NTSTATUS OnRequestComplete(IN PDEVICE_OBJECT fdo, IN PIRP Irp,
IN PKEVENT pev)
{ // OnRequestComplete
KeSetEvent(pev, 0, FALSE);
return STATUS_MORE_PROCESSING_REQUIRED;
} // OnRequestComplete
VOID OnCancelActiveIrp(IN PDEVICE_OBJECT fdo, IN PIRP Irp)
{ // OnCancelActiveIrp
if (fdo->CurrentIrp == Irp)
{ // canceling active IRP
IoReleaseCancelSpinLock(Irp->CancelIrql);
IoStartNextPacket(fdo, TRUE);
CompleteRequest(Irp, STATUS_CANCELLED, 0);
UnlockDevice(fdo);
} // canceling active IRP
else
IoReleaseCancelSpinLock(Irp->CancelIrql);
} // OnCancelActiveIrp
VOID StopDevice(IN PDEVICE_OBJECT fdo)
{ // StopDevice
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
if (!pdx->started)
return;
pdx->started = FALSE;
} // StopDevice
VOID StartIo(IN PDEVICE_OBJECT fdo, IN PIRP Irp)
{ // StartIo
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
KIRQL oldirql;
DbgPrint("Entering startio.\n");
IoAcquireCancelSpinLock(&oldirql);
if (Irp != fdo->CurrentIrp || Irp->Cancel)
{ // request has been cancelled
IoReleaseCancelSpinLock(oldirql);
return;
} // request has been cancelled
else
{ // switch cancel routines
IoSetCancelRoutine(Irp, OnCancelActiveIrp);
IoReleaseCancelSpinLock(oldirql);
} // switch cancel routines
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
pdx->buffer = (PUCHAR) Irp->AssociatedIrp.SystemBuffer;
pdx->nbytes = stack->Parameters.Write.Length; //For write
pdx->numxfer = 0;
} // StartIo
NTSTATUS RequestCreate(IN PDEVICE_OBJECT fdo, IN PIRP Irp)
{ // RequestCreate
DbgPrint("Entering IRP_MJ_CREAT\n");
return CompleteRequest(Irp, STATUS_SUCCESS, 0);
} // RequestCreate
NTSTATUS RequestClose(IN PDEVICE_OBJECT fdo, IN PIRP Irp)
{ // RequestClose
DbgPrint("Entering IRP_MJ_CLOSE\n");
return CompleteRequest(Irp, STATUS_SUCCESS, 0);
} // RequestClose
NTSTATUS CompleteRequest(IN PIRP Irp, IN NTSTATUS status, IN ULONG info)
{ // CompleteRequest
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = info;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
} // CompleteRequest
NTSTATUS RequestControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
PIO_STACK_LOCATION IrpStack;
ULONG ControlCode;
ULONG InputLength,OutputLength;
NTSTATUS status;
IrpStack=IoGetCurrentIrpStackLocation(Irp);
ControlCode=IrpStack->Parameters.DeviceIoControl.IoControlCode;
InputLength=IrpStack->Parameters.DeviceIoControl.InputBufferLength;
OutputLength=IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
switch(ControlCode)
{
case HELLOWDM_IOCTL_HELLO: DbgPrint("Hello from WDM.\n"); status=STATUS_SUCCESS;
break;
default:
status=STATUS_INVALID_DEVICE_REQUEST;
}
return CompleteRequest(Irp, status, 0);
}
void UnlockDevice(PDEVICE_EXTENSION pdx)
{ // UnlockDevice
LONG usage = InterlockedDecrement(&pdx->usage);
if (usage == 0)
KeSetEvent(&pdx->evRemove, 0, FALSE);
} // UnlockDevice
void UnlockDevice(PDEVICE_OBJECT fdo)
{
UnlockDevice((PDEVICE_EXTENSION) fdo->DeviceExtension);
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -