应用程序 function.h function.cpp main.cpp
#ifndef FUNCTION_H #define FUNCTION_H //#include "../MyDriver/Ioctls.h" DWORD ReadPort(HANDLE hDevice,DWORD port); VOID WritePort(HANDLE hDevice,DWORD port,DWORD value); VOID TestDriver(HANDLE hDevice); #endif #include <windows.h> #include <stdio.h> #include "function.h" // DWORD ReadPort(HANDLE hDevice,DWORD port) // { // DWORD dwOutput; // DWORD dwRead; // DeviceIoControl(hDevice, IOCTL_READ_PORT_ULONG, &port, 4, &dwOutput, 4, &dwRead, NULL); // return dwOutput; // } // VOID WritePort(HANDLE hDevice,DWORD port,DWORD value) // { // PVOID buffer[2]; // buffer[0] = (PVOID)port; // buffer[1] = (PVOID)value; // DWORD dwWrite; // DeviceIoControl(hDevice, IOCTL_WRITE_PORT_ULONG, &port, 8, NULL, 0, &dwWrite, NULL); // } // VOID TestDriver(HANDLE hDevice) // { // DWORD dwOutput; // DeviceIoControl(hDevice, IOCTL_TEST, NULL, 0, NULL, 0, &dwOutput, NULL); // } #include <windows.h> #include <stdio.h> //使用CTL_CODE必须加入winioctl.h #include <winioctl.h> #include "..\驱动1\Ioctls.h" int main() { HANDLE hDevice = CreateFile(L"\\\\.\\HelloDDK", GENERIC_READ | GENERIC_WRITE, 0, // share mode none NULL, // no security OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); // no template if (hDevice == INVALID_HANDLE_VALUE) { printf("Failed to obtain file handle to device: " "%s with Win32 error code: %d\n", "MyWDMDevice", GetLastError() ); return 1; } DWORD dwOutput ; DWORD inputBuffer[3] = { 0x378,//对0x378进行操作 1,//1代表8位操作,2代表16位操作,4代表32位操作 0//输出字节0 }; //类似于Out_8((PUCHAR)0x378,0); DeviceIoControl(hDevice, WRITE_PORT, inputBuffer, sizeof(inputBuffer), NULL, 0, &dwOutput, NULL); system("pause"); DeviceIoControl(hDevice, READ_PORT, inputBuffer, sizeof(inputBuffer), NULL, 0, &dwOutput, NULL); system("pause"); CloseHandle(hDevice); return 0; }
Driver.h Ioctls.h Driver.cpp
/************************************************************************ * 文件名称:Driver.h * 作 者:张帆 * 完成日期:2007-11-1 *************************************************************************/ #pragma once #ifdef __cplusplus extern "C" { #endif #include <NTDDK.h> #ifdef __cplusplus } #endif #include "ioctls.h" #define PAGEDCODE code_seg("PAGE") #define LOCKEDCODE code_seg() #define INITCODE code_seg("INIT") #define PAGEDDATA data_seg("PAGE") #define LOCKEDDATA data_seg() #define INITDATA data_seg("INIT") #define arraysize(p) (sizeof(p)/sizeof((p)[0])) #define MAX_FILE_LENGTH 1024 typedef struct _DEVICE_EXTENSION { PDEVICE_OBJECT pDevice; UNICODE_STRING ustrDeviceName; //设备名称 UNICODE_STRING ustrSymLinkName; //符号链接名 PUCHAR buffer;//缓冲区 ULONG file_length;//模拟的文件长度,必须小于MAX_FILE_LENGTH } DEVICE_EXTENSION, *PDEVICE_EXTENSION; // 函数声明 NTSTATUS CreateDevice (IN PDRIVER_OBJECT pDriverObject); VOID HelloDDKUnload (IN PDRIVER_OBJECT pDriverObject); NTSTATUS HelloDDKDispatchRoutin(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp); NTSTATUS HelloDDKDeviceIOControl(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp); // IOCTLS.H -- IOCTL code definitions for fileio driver // Copyright (C) 1999 by Walter Oney // All rights reserved #ifndef IOCTLS_H #define IOCTLS_H #ifndef CTL_CODE #pragma message("CTL_CODE undefined. Include winioctl.h or wdm.h") #endif #define READ_PORT CTL_CODE(\ FILE_DEVICE_UNKNOWN, \ 0x800, \ METHOD_BUFFERED, \ FILE_ANY_ACCESS) #define WRITE_PORT CTL_CODE(\ FILE_DEVICE_UNKNOWN, \ 0x801, \ METHOD_BUFFERED, \ FILE_ANY_ACCESS) #endif #include "Driver.h" /************************************************************************ * 函数名称:DriverEntry * 功能描述:初始化驱动程序,定位和申请硬件资源,创建内核对象 * 参数列表: pDriverObject:从I/O管理器中传进来的驱动对象 pRegistryPath:驱动程序在注册表的中的路径 * 返回 值:返回初始化驱动状态 *************************************************************************/ #pragma INITCODE extern "C" NTSTATUS DriverEntry (IN PDRIVER_OBJECT pDriverObject,IN PUNICODE_STRING pRegistryPath ) { NTSTATUS status; KdPrint(("Enter DriverEntry\n")); pDriverObject->DriverUnload = HelloDDKUnload;//设置卸载函数 for (int i = 0; i < arraysize(pDriverObject->MajorFunction); ++i) pDriverObject->MajorFunction[i] = HelloDDKDispatchRoutin;//设置派遣函数 pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = HelloDDKDeviceIOControl; status = CreateDevice(pDriverObject);//创建驱动设备对象 KdPrint(("Leave DriverEntry\n")); return status; } /************************************************************************ * 函数名称:CreateDevice * 功能描述:初始化设备对象 * 参数列表: pDriverObject:从I/O管理器中传进来的驱动对象 * 返回 值:返回初始化状态 *************************************************************************/ #pragma INITCODE NTSTATUS CreateDevice (IN PDRIVER_OBJECT pDriverObject) { NTSTATUS status; PDEVICE_OBJECT pDevObj; PDEVICE_EXTENSION pDevExt; //创建设备名称 UNICODE_STRING devName; RtlInitUnicodeString(&devName,L"\\Device\\MyDDKDevice"); //创建设备 status = IoCreateDevice( pDriverObject,sizeof(DEVICE_EXTENSION),&(UNICODE_STRING)devName,FILE_DEVICE_UNKNOWN,0, TRUE,&pDevObj ); if (!NT_SUCCESS(status)) return status; pDevObj->Flags |= DO_DIRECT_IO; pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension; pDevExt->pDevice = pDevObj; pDevExt->ustrDeviceName = devName; //申请模拟文件的缓冲区 pDevExt->buffer = (PUCHAR)ExAllocatePool(PagedPool,MAX_FILE_LENGTH); //设置模拟文件大小 pDevExt->file_length = 0; //创建符号链接 UNICODE_STRING symLinkName; RtlInitUnicodeString(&symLinkName,L"\\??\\HelloDDK"); pDevExt->ustrSymLinkName = symLinkName; status = IoCreateSymbolicLink( &symLinkName,&devName ); if (!NT_SUCCESS(status)) { IoDeleteDevice( pDevObj ); return status; } return STATUS_SUCCESS; } /************************************************************************ * 函数名称:HelloDDKUnload * 功能描述:负责驱动程序的卸载操作 * 参数列表: pDriverObject:驱动对象 * 返回 值:返回状态 *************************************************************************/ #pragma PAGEDCODE VOID HelloDDKUnload (IN PDRIVER_OBJECT pDriverObject) { PDEVICE_OBJECT pNextObj; KdPrint(("Enter DriverUnload\n")); pNextObj = pDriverObject->DeviceObject; //while (pNextObj != NULL) //{ // PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION) // pNextObj->DeviceExtension; // if (pDevExt->buffer) // { // ExFreePool(pDevExt->buffer); // pDevExt->buffer = NULL; // } // //删除符号链接 // UNICODE_STRING pLinkName = pDevExt->ustrSymLinkName; // IoDeleteSymbolicLink(&pLinkName); // pNextObj = pNextObj->NextDevice; // IoDeleteDevice( pDevExt->pDevice ); //} UNICODE_STRING symLinkName; RtlInitUnicodeString(&symLinkName, L"\\??\\HelloDDK"); IoDeleteSymbolicLink(&symLinkName);//删除符号连接 IoDeleteDevice(pDriverObject->DeviceObject);//删除设备 } /************************************************************************ * 函数名称:HelloDDKDispatchRoutin * 功能描述:对读IRP进行处理 * 参数列表: pDevObj:功能设备对象 pIrp:从IO请求包 * 返回 值:返回状态 *************************************************************************/ #pragma PAGEDCODE NTSTATUS HelloDDKDispatchRoutin(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp) { KdPrint(("Enter HelloDDKDispatchRoutin\n")); PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp); //建立一个字符串数组与IRP类型对应起来 static char* irpname[] = { "IRP_MJ_CREATE", "IRP_MJ_CREATE_NAMED_PIPE", "IRP_MJ_CLOSE", "IRP_MJ_READ", "IRP_MJ_WRITE", "IRP_MJ_QUERY_INFORMATION", "IRP_MJ_SET_INFORMATION", "IRP_MJ_QUERY_EA", "IRP_MJ_SET_EA", "IRP_MJ_FLUSH_BUFFERS", "IRP_MJ_QUERY_VOLUME_INFORMATION", "IRP_MJ_SET_VOLUME_INFORMATION", "IRP_MJ_DIRECTORY_CONTROL", "IRP_MJ_FILE_SYSTEM_CONTROL", "IRP_MJ_DEVICE_CONTROL", "IRP_MJ_INTERNAL_DEVICE_CONTROL", "IRP_MJ_SHUTDOWN", "IRP_MJ_LOCK_CONTROL", "IRP_MJ_CLEANUP", "IRP_MJ_CREATE_MAILSLOT", "IRP_MJ_QUERY_SECURITY", "IRP_MJ_SET_SECURITY", "IRP_MJ_POWER", "IRP_MJ_SYSTEM_CONTROL", "IRP_MJ_DEVICE_CHANGE", "IRP_MJ_QUERY_QUOTA", "IRP_MJ_SET_QUOTA", "IRP_MJ_PNP", }; UCHAR type = stack->MajorFunction; if (type >= arraysize(irpname)) KdPrint((" - Unknown IRP, major type %X\n", type)); else KdPrint(("\t%s\n", irpname[type])); NTSTATUS status = STATUS_SUCCESS; // 完成IRP pIrp->IoStatus.Status = status; pIrp->IoStatus.Information = 0; // bytes xfered IoCompleteRequest( pIrp, IO_NO_INCREMENT ); KdPrint(("Leave HelloDDKDispatchRoutin\n")); return status; } #pragma PAGEDCODE NTSTATUS HelloDDKDeviceIOControl(IN PDEVICE_OBJECT pDevObj,IN PIRP pIrp) { NTSTATUS status = STATUS_SUCCESS; KdPrint(("Enter HelloDDKDeviceIOControl\n")); //得到当前堆栈 PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp); ULONG cbin = stack->Parameters.DeviceIoControl.InputBufferLength;//得到输入缓冲区大小 ULONG cbout = stack->Parameters.DeviceIoControl.OutputBufferLength;//得到输出缓冲区大小 ULONG code = stack->Parameters.DeviceIoControl.IoControlCode;//得到IOCTL码 ULONG info = 0; switch (code) { // process request case READ_PORT: { KdPrint(("进入驱动读 READ_PORT\n")); //缓冲区方式IOCTL //显示输入缓冲区数据 PULONG InputBuffer = (PULONG)pIrp->AssociatedIrp.SystemBuffer; ULONG port = (ULONG)(*InputBuffer); InputBuffer++; UCHAR method = (UCHAR)(*InputBuffer); //操作输出缓冲区 PULONG OutputBuffer = (PULONG)pIrp->AssociatedIrp.SystemBuffer; if (method==1)//8位操作 { *OutputBuffer = READ_PORT_UCHAR((PUCHAR)port); }else if(method==2)//16位操作 { *OutputBuffer = READ_PORT_USHORT((PUSHORT)port); }else if(method==4)//32位操作 { *OutputBuffer = READ_PORT_ULONG((PULONG)port); } //设置实际操作输出缓冲区长度 info = 4; break; } case WRITE_PORT: { KdPrint(("进入驱动写 WRITE_PORT\n")); //缓冲区方式IOCTL //显示输入缓冲区数据 PULONG InputBuffer = (PULONG)pIrp->AssociatedIrp.SystemBuffer; ULONG port = (ULONG)(*InputBuffer); InputBuffer++; UCHAR method = (UCHAR)(*InputBuffer); InputBuffer++; ULONG value = (ULONG)(*InputBuffer); //操作输出缓冲区 PULONG OutputBuffer = (PULONG)pIrp->AssociatedIrp.SystemBuffer; if (method==1)//8位操作 { WRITE_PORT_UCHAR((PUCHAR)port,(UCHAR)value);//端口号 输出为0 }else if(method==2)//16位操作 { WRITE_PORT_USHORT((PUSHORT)port,(USHORT)value); }else if(method==4)//32位操作 { WRITE_PORT_ULONG((PULONG)port,(ULONG)value); } //设置实际操作输出缓冲区长度 info = 0; break; } default: status = STATUS_INVALID_VARIANT; } // 完成IRP pIrp->IoStatus.Status = status; pIrp->IoStatus.Information = info; // bytes xfered IoCompleteRequest( pIrp, IO_NO_INCREMENT ); KdPrint(("Leave HelloDDKDeviceIOControl\n")); return status; }