以上就是用戶模式下的控制程序了,下面來看看我們的驅動程序。
代碼:unit VirtToPhys;
interface
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: