Delphi研究之驱动开发篇(三)--一个完整的驱动程序示例(下)
以上就是用户模式下的控制程序了,下面来看看我们的驱动程序。
代码:unit VirtToPhys;
inte易做图ce
uses
nt_status, ntoskrnl, ntutils;
function _DriverEntry(pDriverObject:PDRIVER_OBJECT; pusRegistryPath:PUNICODE_STRING): NTSTATUS; stdcall;
implementation
const
NUM_DATA_ENTRY = 4;
DATA_SIZE = sizeof(DWORD) * NUM_DATA_ENTRY;
var
g_usDeviceName, g_usSymbolicLinkName: UNICODE_STRING;
function DispatchCreateClose(p_DeviceObject:PDEVICE_OBJECT; p_Irp:PIRP): NTSTATUS; stdcall;
begin
p_Irp^.IoStatus.Status := STATUS_SUCCESS;
p_Irp^.IoStatus.Information := 0;
IofCompleteRequest(p_Irp, IO_NO_INCREMENT);
result := STATUS_SUCCESS;
end;
function DispatchControl(p_DeviceObject: PDEVICE_OBJECT; p_Irp:PIRP): NTSTATUS; stdcall;
var
status:NTSTATUS;
dwBytesReturned:DWORD;
psl:PIO_STACK_LOCATION;
IOCTL_GET_PHYS_ADDRESS: DWORD;
pSystemBuffer: PULONG;
iCnt: DWORD;
liPhysicalAddress: PHYSICAL_ADDRESS;
begin
dwBytesReturned := 0;
IOCTL_GET_PHYS_ADDRESS := CTL_CODE(FILE_DEVICE_UNKNOWN,
$800, METHOD_BUFFERED, FILE_READ_ACCESS + FILE_WRITE_ACCESS);
psl := IoGetCurrentIrpStackLocation(p_Irp);
if psl^.Parameters.DeviceIoControl.IoControlCode = IOCTL_GET_PHYS_ADDRESS then
begin
if (psl^.Parameters.DeviceIoControl.OutputBufferLength >= DATA_SIZE)
and (psl^.Parameters.DeviceIoControl.InputBufferLength >= DATA_SIZE) then
begin
pSystemBuffer := p_Irp^.AssociatedIrp.SystemBuffer;
iCnt := 0;
for iCnt := 1 to NUM_DATA_ENTRY do
begin
liPhysicalAddress := MmGetPhysicalAddress(PVOID(pSystemBuffer^));
pSystemBuffer^ := liPhysicalAddress.LowPart;
inc(pSystemBuffer);
end;
dwBytesReturned := DATA_SIZE;
status := STATUS_SUCCESS;
end else
begin
status := STATUS_BUFFER_TOO_SMALL;
end;
end else
begin
status := STATUS_INVALID_DEVICE_REQUEST;
end;
p_Irp^.IoStatus.Status := status;
p_Irp^.IoStatus.Information := dwBytesReturned;
IofCompleteRequest(p_Irp, IO_NO_INCREMENT);
result := status;
end;
procedure DriverUnload(p_DriverObject:PDRIVER_OBJECT); stdcall;
begin
IoDeleteSymbolicLink(@g_usSymbolicLinkName);
IoDeleteDevice(p_DriverObject^.DeviceObject);
end;
function _DriverEntry(pDriverObject:PDRIVER_OBJECT; pusRegistryPath:PUNICODE_STRING): NTSTATUS;
var
status:NTSTATUS;
pDeviceObject:TDeviceObject;
begin
status := STATUS_DEVICE_CONFIGURATION_ERROR;
RtlInitUnicodeString(g_usDeviceName, DevicedevVirtToPhys);
RtlInitUnicodeString(g_usSymbolicLinkName, ??slVirtToPhys);
if (IoCreateDevice(pDriverObject, 0, @g_usDeviceName,
FILE_DEVICE_UNKNOWN, 0, FALSE,
pDeviceObject) = STATUS_SUCCESS) then
begin
if (IoCreateSymbolicLink(@g_usSymbolicLinkName,
@g_usDeviceName) = STATUS_SUCCESS) then
begin
pDriverObject^.MajorFunction[IRP_MJ_Create] := @DispatchCreateClose;
pDriverObject^.MajorFunction[IRP_MJ_CLOSE] := @DispatchCreateClose;
pDriverObject^.MajorFunction[IRP_MJ_DEVICE_CONTROL] := @DispatchControl;
pDriverObject^.DriverUnload := @DriverUnload;
status := STATUS_SUCCESS;
end else
begin
IoDeleteDevice(@pDeviceObject);
end;
end;
result := status;
end;
end.
程序很简单,所以一行注释也没加^_^。既然驱动程序的主要作用是用于控制一些设备,包括物理设备、虚拟设备或者逻辑设备,那么我们首先必须将这些设备创建起来(本例中是虚拟设备),这可以通过调用IoCreateDevice函数来完成,函数将创建并初始化一个由驱动程序使用的设备对象(DEVICE_OBJECT结构),其原型如下:
代码:function IoCreateDevice(DriverObject: PDRIVER_OBJECT;
DeviceExtensionSize: ULONG;
DeviceName: PUNICODE_STRING;
DeviceType: DEVICE_TYPE;
DeviceCharacteristics: ULONG;
Exclusive:
补充:软件开发 , Delphi ,