在WinNT下Ring3级应用程序不能直接访问硬件I/O和物理内存,需要调用驱动在Ring0下间接访问。本代码在MASM10 + KmdKit v1.8下编译通过。
comment *
libmio.asm -- Using driver to implement hardware access for Windows.
allows the ring3 applications to access I/O port,MSR,PMC,PCI bus,Physical memory.
2011/08/15 Perry<ppsoft268@gmail.com>
*
.586
.model flat, stdcall
option casemap :none
KmdKit头文件。
include w2k\ntddk.inc
include w2k\ntstatus.inc
include w2k\ntoskrnl.inc
include w2k\hal.inc
include Strings.mac
KmdKit库文件。
includelib \masm32\lib\w2k\ntoskrnl.lib
includelib \masm32\lib\w2k\hal.lib
驱动入口函数声明。
DriverEntry PROTO :PDRIVER_OBJECT,:PUNICODE_STRING
驱动I/O例程调用函数声明。
OnUnrealized PROTO :PDEVICE_OBJECT,:PIRP
OnIoControl PROTO :PDEVICE_OBJECT,:PIRP
OnCreate PROTO :PDEVICE_OBJECT,:PIRP
OnClose PROTO :PDEVICE_OBJECT,:PIRP
OnUnload PROTO :PDRIVER_OBJECT
物理内存读写函数声明。
MmMapPhysical PROTO :DWORD,:DWORD,:DWORD
MmUnmapPhysical PROTO :DWORD
本驱动版本常数。
LIBMIO_MAJOR_VERSION equ 1h
LIBMIO_MINOR_VERSION equ 0h
LIBMIO_REVISION equ 0h
LIBMIO_RELESE equ 2h
内核内存分配标记。
MM_ALLOC_POOL_TAG equ 6d62696ch
接受DeviceIoControl的常量定义。
IOCTL_GET_DRIVER_REFCOUNT equ CTL_CODE(FILE_DEVICE_UNKNOWN, 8FFh, METHOD_BUFFERED, FILE_ANY_ACCESS)
IOCTL_GET_DRIVER_VERSION equ CTL_CODE(FILE_DEVICE_UNKNOWN, 900h, METHOD_BUFFERED, FILE_ANY_ACCESS)
IOCTL_READ_MSR equ CTL_CODE(FILE_DEVICE_UNKNOWN, 901h, METHOD_BUFFERED, FILE_ANY_ACCESS)
IOCTL_WRITE_MSR equ CTL_CODE(FILE_DEVICE_UNKNOWN, 902h, METHOD_BUFFERED, FILE_ANY_ACCESS)
IOCTL_READ_PMC equ CTL_CODE(FILE_DEVICE_UNKNOWN, 903h, METHOD_BUFFERED, FILE_ANY_ACCESS)
IOCTL_HALT equ CTL_CODE(FILE_DEVICE_UNKNOWN, 904h, METHOD_BUFFERED, FILE_ANY_ACCESS)
IOCTL_READ_PORT equ CTL_CODE(FILE_DEVICE_UNKNOWN, 905h, METHOD_BUFFERED, FILE_ANY_ACCESS)
IOCTL_READ_PORT_BYTE equ CTL_CODE(FILE_DEVICE_UNKNOWN, 906h, METHOD_BUFFERED, FILE_ANY_ACCESS)
IOCTL_READ_PORT_WORD equ CTL_CODE(FILE_DEVICE_UNKNOWN, 907h, METHOD_BUFFERED, FILE_ANY_ACCESS)
IOCTL_READ_PORT_DWORD equ CTL_CODE(FILE_DEVICE_UNKNOWN, 908h, METHOD_BUFFERED, FILE_ANY_ACCESS)
IOCTL_WRITE_PORT equ CTL_CODE(FILE_DEVICE_UNKNOWN, 909h, METHOD_BUFFERED, FILE_ANY_ACCESS)
IOCTL_WRITE_PORT_BYTE equ CTL_CODE(FILE_DEVICE_UNKNOWN, 90Ah, METHOD_BUFFERED, FILE_ANY_ACCESS)
IOCTL_WRITE_PORT_WORD equ CTL_CODE(FILE_DEVICE_UNKNOWN, 90Bh, METHOD_BUFFERED, FILE_ANY_ACCESS)
IOCTL_WRITE_PORT_DWORD equ CTL_CODE(FILE_DEVICE_UNKNOWN, 90Ch, METHOD_BUFFERED, FILE_ANY_ACCESS)
IOCTL_PCI_READ_CONFIG equ CTL_CODE(FILE_DEVICE_UNKNOWN, 90Dh, METHOD_BUFFERED, FILE_ANY_ACCESS)
IOCTL_PCI_WRITE_CONFIG equ CTL_CODE(FILE_DEVICE_UNKNOWN, 90Eh, METHOD_BUFFERED, FILE_ANY_ACCESS)
IOCTL_MAP_PHY_MEMORY equ CTL_CODE(FILE_DEVICE_UNKNOWN, 90Fh, METHOD_BUFFERED, FILE_ANY_ACCESS)
IOCTL_UNMAP_PHY_MEMORY equ CTL_CODE(FILE_DEVICE_UNKNOWN, 910h, METHOD_BUFFERED, FILE_ANY_ACCESS)
IOCTL_READ_PHY_MEMORY equ CTL_CODE(FILE_DEVICE_UNKNOWN, 911h, METHOD_BUFFERED, FILE_ANY_ACCESS)
IOCTL_WRITE_PHY_MEMORY equ CTL_CODE(FILE_DEVICE_UNKNOWN, 912h, METHOD_BUFFERED, FILE_ANY_ACCESS)
物理内存分配信息结构定义。
_MAP_NODE struct
node SINGLE_LIST_ENTRY <?>
pid dd ?
pMdl dd ?
ppAddr dd ?
pvKenl dd ?
pvUser dd ?
cbSize dd ?
_MAP_NODE ends
MAP_NODE typedef _MAP_NODE
PMAP_NODE typedef PTR _MAP_NODE
Windows驱动符号定义。
.const
CCOUNTED_UNICODE_STRING "\\Device\\libmio", uzWinDeviceName, 4
CCOUNTED_UNICODE_STRING "\\DosDevices\\libmio", uzDosDeviceName, 4
.data?
MapList SINGLE_LIST_ENTRY <?>
.data
dwLibmioVersion db LIBMIO_RELESE
db LIBMIO_REVISION
db LIBMIO_MINOR_VERSION
db LIBMIO_MAJOR_VERSION
dwRefCount dd 0
mmnode MAP_NODE <<?>,0,0,0,0,0,0>
入口函数。
.code
; This function is called by the system.
; initialize some resource and create a new device object.
; Arguments:
; DriverObject - Pointer to the object that represents our driver.
; RegistryPath - Pointer to the unicode string for the registry path of driver.
; Return Value:
; STATUS_SUCCESS if the driver initialized correctly, otherwise an erroror
; indicating the reason for failure.
DriverEntry proc DriverObject:PDRIVER_OBJECT, RegistryPath:PUNICODE_STRING
LOCAL pDeviceObject :PDEVICE_OBJECT
LOCAL ntStatus :NTSTATUS
INVOKE DbgPrint, $CTA0("DriverEntry: Enter...\n")
; protect register
pushad
lea esi, MapList
assume esi: PSINGLE_LIST_ENTRY
mov [esi].Next, NULL
assume esi: nothing
mov esi, DriverObject
assume esi: PDRIVER_OBJECT
mov pDeviceObject, NULL
; create a new DeviceObject
INVOKE IoCreateDevice, esi, 0h, addr uzWinDeviceName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, 0, addr pDeviceObject
mov ntStatus, eax
INVOKE DbgPrint, $CTA0("DriverEntry: IoCreateDevice(%08X)\n"), ntStatus
cmp ntStatus, STATUS_SUCCESS
jnz @F
mov [esi].MajorFunction[(sizeof PVOID) * IRP_MJ_CLOSE], offset OnClose
mov [esi].MajorFunction[(sizeof PVOID) * IRP_MJ_CREATE], offset OnCreate
mov [esi].MajorFunction[(sizeof PVOID) * IRP_MJ_DEVICE_CONTROL], offset OnIoControl
mov eax, offset OnUnrealized
mov [esi].MajorFunction[(sizeof PVOID) * IRP_MJ_INTERNAL_DEVICE_CONTROL], eax
mov [esi].MajorFunction[(sizeof PVOID) * IRP_MJ_SYSTEM_CONTROL], eax
mov [esi].MajorFunction[(sizeof PVOID) * IRP_MJ_POWER], eax
mov [esi].MajorFunction[(sizeof PVOID) * IRP_MJ_PNP], eax
mov [esi].DriverUnload, offset OnUnload
; link the pDeviceObject
INVOKE IoCreateSymbolicLink, addr uzDosDeviceName, addr uzWinDeviceName
mov ntStatus, eax
INVOKE DbgPrint, $CTA0("DriverEntry: IoCreateSymbolicLink(%08X)\n"), ntStatus
cmp ntStatus, STATUS_SUCCESS
jz @F
; if the IoCreateSymbolicLink was have not succeed.
; We need to delete the pDeviceObject for created by IoCreateDevice.
INVOKE IoDeleteDevice, pDeviceObject
INVOKE DbgPrint, $CTA0("DriverEntry: IoDeleteDevice()\n")
@@:
assume esi: nothing
popad
INVOKE DbgPrint, $CTA0("DriverEntry: Leave...\n\n")
mov eax, ntStatus
ret
DriverEntry endp
未处理的例程。
; other IRP.
; Arguments:
; DeviceObject - Pointer to device object.
; pIrp - Pointer to the current IRP.
; Return Value:
; STATUS_SUCCESS if the IRP was processed successfully, otherwise an erroror
; indicating the reason for failure.
OnUnrealized proc uses esi pDeviceObject:PDEVICE_OBJECT, pIrp:PIRP
INVOKE DbgPrint, $CTA0("OnUnrealized: Enter...\n")
push esi
mov esi, pIrp
assume esi :PIRP
mov [esi].IoStatus.Status, STATUS_SUCCESS
mov [esi].IoStatus.Information, 0h
assume esi :nothing
pop esi
fastcall IofCompleteRequest, pIrp, IO_NO_INCREMENT
INVOKE DbgPrint, $CTA0("OnUnrealized: IoCompleteRequest()\n")
INVOKE DbgPrint, $CTA0("OnUnrealized: Leave...\n\n")
mov eax, STATUS_SUCCESS
ret
OnUnrealized endp
处理应用程式发送的DeviceIoControl例程。
; IRP_MJ_DEVICE_CONTROL.
; Arguments:
; DeviceObject - Pointer to device object.
; pIrp - Pointer to the current IRP.
; Return Value:
; STATUS_SUCCESS if the IRP was processed successfully, otherwise an erroror
; indicating the reason for failure.
OnIoControl proc uses esi edi ebx pDeviceObject:PDEVICE_OBJECT, pIrp:PIRP
LOCAL ntStatus :NTSTATUS
INVOKE DbgPrint, $CTA0("OnIoControl: Enter...\n")
mov ntStatus, STATUS_INVALID_DEVICE_REQUEST
mov esi, pIrp
assume esi :PIRP
mov [esi].IoStatus.Information, 0h
IoGetCurrentIrpStackLocation esi
mov edi, eax
assume edi :PIO_STACK_LOCATION
获取驱动被调用的实例数量,使驱动能被多个Ring3应用程序调用。
.if [edi].Parameters.DeviceIoControl.IoControlCode == IOCTL_GET_DRIVER_REFCOUNT
INVOKE DbgPrint, $CTA0("OnIoControl: $IOCTL_GET_DRIVER_REFCOUNT\n")
mov ntStatus, STATUS_BUFFER_TOO_SMALL
cmp [edi].Parameters.DeviceIoControl.OutputBufferLength, 4h
jb @F
mov eax, [esi].AssociatedIrp.SystemBuffer
mov ecx, dwRefCount
mov [eax], ecx
mov [esi].IoStatus.Information, 4h
mov ntStatus, STATUS_SUCCESS
@@:
获取驱动内部版本号。
.elseif [edi].Parameters.DeviceIoControl.IoControlCode == IOCTL_GET_DRIVER_VERSION
INVOKE DbgPrint, $CTA0("OnIoControl: $IOCTL_GET_DRIVER_VERSION\n")
mov ntStatus, STATUS_BUFFER_TOO_SMALL
cmp [edi].Parameters.DeviceIoControl.OutputBufferLength, 4h
jb @F
mov eax, [esi].AssociatedIrp.SystemBuffer
lea ebx, dwLibmioVersion
mov ecx, [ebx]
mov [eax], ecx
mov [esi].IoStatus.Information, 4h
mov ntStatus, STATUS_SUCCESS
@@:
读取MSR寄存器。
.elseif [edi].Parameters.DeviceIoControl.IoControlCode == IOCTL_READ_MSR
INVOKE DbgPrint, $CTA0("OnIoControl: $IOCTL_READ_MSR\n")
mov ntStatus, STATUS_BUFFER_TOO_SMALL
cmp [edi].Parameters.DeviceIoControl.InputBufferLength, 4h
jb @F
cmp [edi].Parameters.DeviceIoControl.OutputBufferLength, 8h
jb @F
mov ebx, [esi].AssociatedIrp.SystemBuffer
mov ecx, [ebx]
rdmsr
mov [ebx], eax
mov [ebx + 4h], edx
mov [esi].IoStatus.Information, 8h
mov ntStatus, STATUS_SUCCESS
@@:
写MSR寄存器。
.elseif [edi].Parameters.DeviceIoControl.IoControlCode == IOCTL_WRITE_MSR
INVOKE DbgPrint, $CTA0("OnIoControl: $IOCTL_WRITE_MSR\n")
mov ntStatus, STATUS_BUFFER_TOO_SMALL
cmp [edi].Parameters.DeviceIoControl.InputBufferLength, 0Ch
jb @F
mov ebx, [esi].AssociatedIrp.SystemBuffer
mov ecx, [ebx]
mov eax, [ebx + 4h]
mov edx, [ebx + 8h]
wrmsr
mov ntStatus, STATUS_SUCCESS
@@:
读取PMC信息。
.elseif [edi].Parameters.DeviceIoControl.IoControlCode == IOCTL_READ_PMC
INVOKE DbgPrint, $CTA0("OnIoControl: $IOCTL_READ_PMC\n")
mov ntStatus, STATUS_BUFFER_TOO_SMALL
cmp [edi].Parameters.DeviceIoControl.InputBufferLength, 4h
jb @F
cmp [edi].Parameters.DeviceIoControl.OutputBufferLength, 8h
jb @F
mov ebx, [esi].AssociatedIrp.SystemBuffer
mov ecx, [ebx]
rdpmc
mov [ebx], eax
mov [ebx + 4h], edx
mov [esi].IoStatus.Information, 8h
mov ntStatus, STATUS_SUCCESS
@@:
调用Halt特权指令。
.elseif [edi].Parameters.DeviceIoControl.IoControlCode == IOCTL_HALT
hlt
mov ntStatus, STATUS_SUCCESS
.elseif [edi].Parameters.DeviceIoControl.IoControlCode == IOCTL_READ_PORT
INVOKE DbgPrint, $CTA0("OnIoControl: $IOCTL_READ_PORT\n")
mov ntStatus, STATUS_BUFFER_TOO_SMALL
cmp [edi].Parameters.DeviceIoControl.InputBufferLength, 2h
jb @F
cmp [edi].Parameters.DeviceIoControl.OutputBufferLength, 0h
jz @F
mov ebx, [esi].AssociatedIrp.SystemBuffer
mov dx, [ebx]
cli
.if [edi].Parameters.DeviceIoControl.OutputBufferLength >= 4h
in eax, dx
mov [ebx], eax
mov [esi].IoStatus.Information, 4h
.else
.if [edi].Parameters.DeviceIoControl.OutputBufferLength >= 2h
in ax, dx
mov [ebx], ax
mov [esi].IoStatus.Information, 2h
.else
in al, dx
mov [ebx], al
mov [esi].IoStatus.Information, 1h
.endif
.endif
sti
mov ntStatus, STATUS_SUCCESS
@@:
一次读取I/O端口一个字节。
.elseif [edi].Parameters.DeviceIoControl.IoControlCode == IOCTL_READ_PORT_BYTE
INVOKE DbgPrint, $CTA0("OnIoControl: $IOCTL_READ_PORT_BYTE\n")
mov ntStatus, STATUS_BUFFER_TOO_SMALL
cmp [edi].Parameters.DeviceIoControl.InputBufferLength, 2h
jb @F
cmp [edi].Parameters.DeviceIoControl.OutputBufferLength, 0h
jz @F
mov ebx, [esi].AssociatedIrp.SystemBuffer
push ebx
xor eax, eax
mov ax, [ebx]
INVOKE READ_PORT_UCHAR, eax
pop ebx
mov [ebx], al
mov [esi].IoStatus.Information, 1h
mov ntStatus, STATUS_SUCCESS
@@:
一次读取I/O端口两个字节。
.elseif [edi].Parameters.DeviceIoControl.IoControlCode == IOCTL_READ_PORT_WORD
INVOKE DbgPrint, $CTA0("OnIoControl: $IOCTL_READ_PORT_WORD\n")
mov ntStatus, STATUS_BUFFER_TOO_SMALL
cmp [edi].Parameters.DeviceIoControl.InputBufferLength, 2h
jb @F
cmp [edi].Parameters.DeviceIoControl.OutputBufferLength, 2h
jb @F
mov ebx, [esi].AssociatedIrp.SystemBuffer
push ebx
xor eax, eax
mov ax, [ebx]
INVOKE READ_PORT_USHORT, eax
pop ebx
mov [ebx], ax
mov [esi].IoStatus.Information, 2h
mov ntStatus, STATUS_SUCCESS
@@:
一次读取I/O端口四个字节。
.elseif [edi].Parameters.DeviceIoControl.IoControlCode == IOCTL_READ_PORT_DWORD
INVOKE DbgPrint, $CTA0("OnIoControl: $IOCTL_READ_PORT_DWORD\n")
mov ntStatus, STATUS_BUFFER_TOO_SMALL
cmp [edi].Parameters.DeviceIoControl.InputBufferLength, 2h
jb @F
cmp [edi].Parameters.DeviceIoControl.OutputBufferLength, 4h
jb @F
mov ebx, [esi].AssociatedIrp.SystemBuffer
push ebx
xor eax, eax
mov ax, [ebx]
INVOKE READ_PORT_ULONG, eax
pop ebx
mov [ebx], eax
mov [esi].IoStatus.Information, 4h
mov ntStatus, STATUS_SUCCESS
@@:
.elseif [edi].Parameters.DeviceIoControl.IoControlCode == IOCTL_WRITE_PORT
INVOKE DbgPrint, $CTA0("OnIoControl: $IOCTL_WRITE_PORT\n")
mov ntStatus, STATUS_BUFFER_TOO_SMALL
cmp [edi].Parameters.DeviceIoControl.InputBufferLength, 3h
jb @F
mov ebx, [esi].AssociatedIrp.SystemBuffer
mov dx, [ebx]
cli
.if [edi].Parameters.DeviceIoControl.InputBufferLength >= 6h
mov eax, [ebx + 2h]
out dx, eax
.else
.if [edi].Parameters.DeviceIoControl.InputBufferLength >= 4h
mov ax, [ebx + 2h]
out dx, ax
.else
mov al, [ebx + 2h]
out dx, al
.endif
.endif
sti
mov ntStatus, STATUS_SUCCESS
@@:
一次写I/O端口一个字节。
.elseif [edi].Parameters.DeviceIoControl.IoControlCode == IOCTL_WRITE_PORT_BYTE
INVOKE DbgPrint, $CTA0("OnIoControl: $IOCTL_WRITE_PORT_BYTE\n")
mov ntStatus, STATUS_BUFFER_TOO_SMALL
cmp [edi].Parameters.DeviceIoControl.InputBufferLength, 8h
jb @F
mov ebx, [esi].AssociatedIrp.SystemBuffer
mov eax, [ebx]
mov ecx, [ebx + 4h]
INVOKE WRITE_PORT_UCHAR, eax, ecx
mov ntStatus, STATUS_SUCCESS
@@:
一次写I/O端口两个字节。
.elseif [edi].Parameters.DeviceIoControl.IoControlCode == IOCTL_WRITE_PORT_WORD
INVOKE DbgPrint, $CTA0("OnIoControl: $IOCTL_WRITE_PORT_WORD\n")
mov ntStatus, STATUS_BUFFER_TOO_SMALL
cmp [edi].Parameters.DeviceIoControl.InputBufferLength, 8h
jb @F
mov ebx, [esi].AssociatedIrp.SystemBuffer
mov eax, [ebx]
mov ecx, [ebx + 4h]
INVOKE WRITE_PORT_USHORT, eax, ecx
mov ntStatus, STATUS_SUCCESS
@@:
一次写I/O端口四字节。
.elseif [edi].Parameters.DeviceIoControl.IoControlCode == IOCTL_WRITE_PORT_DWORD
INVOKE DbgPrint, $CTA0("OnIoControl: $IOCTL_WRITE_PORT_DWORD\n")
mov ntStatus, STATUS_BUFFER_TOO_SMALL
cmp [edi].Parameters.DeviceIoControl.InputBufferLength, 8h
jb @F
mov ebx, [esi].AssociatedIrp.SystemBuffer
mov eax, [ebx]
mov ecx, [ebx + 4h]
INVOKE WRITE_PORT_ULONG, eax, ecx
mov ntStatus, STATUS_SUCCESS
@@:
读写PCI配置信息。
.elseif [edi].Parameters.DeviceIoControl.IoControlCode == IOCTL_PCI_READ_CONFIG
; SystemBuffer for input.
; DWORD[0] = bus number.
; DWORD[1] = slot number.
; DWORD[2] = offset.
; SystemBuffer for output.
; DWORD = data output.
INVOKE DbgPrint, $CTA0("OnIoControl: $IOCTL_PCI_READ_CONFIG\n")
mov ntStatus, STATUS_BUFFER_TOO_SMALL
cmp [edi].Parameters.DeviceIoControl.InputBufferLength, 0Ch
jb @F
cmp [edi].Parameters.DeviceIoControl.OutputBufferLength, 0h
jz @F
mov ebx, [esi].AssociatedIrp.SystemBuffer
mov eax, [edi].Parameters.DeviceIoControl.OutputBufferLength
INVOKE HalGetBusDataByOffset, PCIConfiguration, [ebx], [ebx + 4h], ebx, [ebx + 8h], eax
.if eax != [edi].Parameters.DeviceIoControl.OutputBufferLength
mov [esi].IoStatus.Information, 0h
mov ntStatus, STATUS_INVALID_PARAMETER
.else
mov [esi].IoStatus.Information, eax
mov ntStatus, STATUS_SUCCESS
.endif
@@:
.elseif [edi].Parameters.DeviceIoControl.IoControlCode == IOCTL_PCI_WRITE_CONFIG
; SystemBuffer for input.
; DWORD[0] = bus number.
; DWORD[1] = slot number.
; DWORD[2] = offset.
; DWORD[3] = data length.
INVOKE DbgPrint, $CTA0("OnIoControl: $IOCTL_PCI_WRITE_CONFIG\n")
mov ntStatus, STATUS_BUFFER_TOO_SMALL
cmp [edi].Parameters.DeviceIoControl.InputBufferLength, 10h
jbe @F
mov ebx, [esi].AssociatedIrp.SystemBuffer
mov eax, ebx
add eax, 10h
push [ebx + 0Ch]
INVOKE HalSetBusDataByOffset, PCIConfiguration, [ebx], [ebx + 4h], eax, [ebx + 8h], [ebx + 0Ch]
pop ebx
.if eax != ebx
mov [esi].IoStatus.Information, 0h
mov ntStatus, STATUS_INVALID_PARAMETER
.else
mov [esi].IoStatus.Information, eax
mov ntStatus, STATUS_SUCCESS
.endif
@@:
.endif
push ntStatus
pop [esi].IoStatus.Status
assume edi :nothing
assume esi :nothing
fastcall IofCompleteRequest, pIrp, IO_NO_INCREMENT
INVOKE DbgPrint, $CTA0("OnIoControl: IoCompleteRequest()\n")
INVOKE DbgPrint, $CTA0("OnIoControl: Leave...\n\n")
mov eax, ntStatus
ret
OnIoControl endp
处理应用程序调用CreateFile的例程。
; IRP_MJ_CREATE.
; Arguments:
; DeviceObject - Pointer to device object.
; pIrp - Pointer to the current IRP.
; Return Value:
; STATUS_SUCCESS if the IRP was processed successfully, otherwise an erroror
; indicating the reason for failure.
OnCreate proc uses esi pDeviceObject:PDEVICE_OBJECT, pIrp:PIRP
INVOKE DbgPrint, $CTA0("OnCreate: Enter...\n")
inc dwRefCount
push esi
mov esi, pIrp
assume esi :PIRP
mov [esi].IoStatus.Status, STATUS_SUCCESS
mov [esi].IoStatus.Information, 0h
assume esi :nothing
pop esi
fastcall IofCompleteRequest, pIrp, IO_NO_INCREMENT
INVOKE DbgPrint, $CTA0("OnCreate: IoCompleteRequest()\n")
INVOKE DbgPrint, $CTA0("OnCreate: Leave...\n\n")
mov eax, STATUS_SUCCESS
ret
OnCreate endp
处理应用程序调用CloseHandle的例程。
; IRP_MJ_CLOSE.
; Arguments:
; DeviceObject - Pointer to device object.
; pIrp - Pointer to the current IRP.
; Return Value:
; STATUS_SUCCESS if the IRP was processed successfully, otherwise an erroror
; indicating the reason for failure.
OnClose proc uses esi pDeviceObject:PDEVICE_OBJECT, pIrp:PIRP
INVOKE DbgPrint, $CTA0("OnClose: Enter...\n")
cmp dwRefCount, 0h
jz @F
dec dwRefCount
@@:
push esi
mov esi, pIrp
assume esi :PIRP
mov [esi].IoStatus.Status, STATUS_SUCCESS
mov [esi].IoStatus.Information, 0h
assume esi :nothing
pop esi
fastcall IofCompleteRequest, pIrp, IO_NO_INCREMENT
INVOKE DbgPrint, $CTA0("OnClose: IoCompleteRequest()\n")
INVOKE DbgPrint, $CTA0("OnClose: Leave...\n\n")
mov eax, STATUS_SUCCESS
ret
OnClose endp
处理系统调用或当应用程序调用DeleteService,ControlService时的例程。
; This routine is called by the I/O system to unload the driver.
; Any resources previously allocated must be freed.
; Arguments:
; DriverObject - Pointer to the object that represents our driver.
; Return Value:
; None
OnUnload proc DriverObject:PDRIVER_OBJECT
INVOKE DbgPrint, $CTA0("OnUnload: Enter...\n")
; delete the link from our device name to a name in the Win32 namespace.
INVOKE IoDeleteSymbolicLink, addr uzDosDeviceName
INVOKE DbgPrint, $CTA0("OnUnload: IoDeleteSymbolicLink(%08X)\n"), eax
; delete the pDeviceObject
mov eax, DriverObject
INVOKE IoDeleteDevice, (DRIVER_OBJECT PTR [eax]).DeviceObject
INVOKE DbgPrint, $CTA0("OnUnload: IoDeleteDevice()\n")
INVOKE DbgPrint, $CTA0("OnUnload: Leave...\n\n")
ret
OnUnload endp