新建exe控制檯程序
#include "pch.h"
#include <windows.h>
#include <iostream>
#include <WinIoCtl.h>
#include "ctl_code.h"
using namespace std;
#pragma warning(disable: 4789)
int add(HANDLE hDevice, int a, int b)
{
int port[2] = {0x00};
int buffret;
ULONG dwWrite;
port[0] = a;
port[1] = b;
::DeviceIoControl(hDevice, add_code, &port, 8, &buffret, 4, &dwWrite, NULL);
return buffret;
}
int main()
{
HANDLE hDevice = ::CreateFileA("\\\\.\\MySysData",
GENERIC_READ|GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hDevice == INVALID_HANDLE_VALUE)
{
cout << "獲取驅動句柄失敗" <<GetLastError() <<endl;
}
int a, b;
while (true)
{
cin >> a >> b;
int r = add(hDevice, a, b);
cout << a << " + " << b << " = " << r << endl;
getchar();
}
std::cout << "Hello World!\n";
}
ctl_code.h代碼
#pragma once
#include <WinIoCtl.h>
#define add_code CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED,FILE_ANY_ACCESS)
#define sub_code CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED,FILE_ANY_ACCESS)
新建kmdf空工程,代碼如下
#include <ntddk.h>
#include "clt_code.h"
#define INITCODE code_seg("INIT");
#define PAGECODE code_seg("PAGE");
NTSTATUS CreateMyDevice(IN PDRIVER_OBJECT pDriverObject)
{
NTSTATUS status;
UNICODE_STRING devName; //設備名稱
UNICODE_STRING sysLinkName; //系統符號鏈接名
PDEVICE_OBJECT pDevObject; //用於返回創建設備
RtlInitUnicodeString(&devName, L"\\Device\\MyDevObj");
status = IoCreateDevice(pDriverObject, 0, &devName, FILE_DEVICE_UNKNOWN, 0, TRUE, &pDevObject);
if (!NT_SUCCESS(status))
{
if (status == STATUS_INSUFFICIENT_RESOURCES)
{
KdPrint(("資源不足\n"));
}
if (status == STATUS_OBJECT_NAME_EXISTS)
{
KdPrint(("指定對象名存在\n"));
}
if (status == STATUS_OBJECT_NAME_COLLISION)
{
KdPrint(("對象名有衝突"));
}
return status;
}
KdPrint(("設備創建成功\n"));
pDevObject->Flags |= DO_BUFFERED_IO; //緩衝區方式讀寫
RtlInitUnicodeString(&sysLinkName, L"\\??\\MySysData");
IoDeleteSymbolicLink(&sysLinkName);
status = IoCreateSymbolicLink(&sysLinkName, &devName); //判斷生成符號鏈接是否成功
if (!NT_SUCCESS(status))
{
KdPrint(("生成符號鏈接失敗\n"));
IoDeleteDevice(pDevObject);
return status;
}
KdPrint(("生成符號鏈接成功"));
return STATUS_SUCCESS;
}
VOID DriverUnload(PDRIVER_OBJECT pDriverObject)
{
PDEVICE_OBJECT pDevObject;
UNICODE_STRING sysLinkName;
pDevObject = pDriverObject->DeviceObject;
IoDeleteDevice(pDevObject); //取得設備並刪除
KdPrint(("成功刪除設備\n"));
RtlInitUnicodeString(&sysLinkName, L"\\??\\MySysData");
IoDeleteSymbolicLink(&sysLinkName); //取得符號鏈接並刪除
KdPrint(("成功刪除符號鏈接\n"));
KdPrint(("驅動成功卸載\n"));
}
//NTSTATUS MyDispatchRoutine(IN PDEVICE_OBJECT pDevobj, IN PIRP pIrp)
//{
// return STATUS_SUCCESS;
//}
NTSTATUS MyDispatchRoutine(IN PDEVICE_OBJECT pDevobj, IN PIRP pIrp)
{
ULONG info;
PIO_STACK_LOCATION psl = IoGetCurrentIrpStackLocation(pIrp);
switch (psl->MajorFunction)
{
case IRP_MJ_CREATE:
break;
case IRP_MJ_CLOSE:
break;
case IRP_MJ_READ:
break;
case IRP_MJ_WRITE:
break;
case IRP_MJ_DEVICE_CONTROL:
{
NTSTATUS status = STATUS_SUCCESS;
ULONG cbin = psl->Parameters.DeviceIoControl.InputBufferLength; //獲取輸入緩衝區大小
ULONG cbout = psl->Parameters.DeviceIoControl.OutputBufferLength; //獲取輸出緩衝區大小
ULONG code = psl->Parameters.DeviceIoControl.IoControlCode; //得到IOCTL
KdPrint(("Enter IRP_MJ_DEVICE_CONTROL\n"));
switch (code)
{
case add_code:
{
int a, b, r;
int * inputBuffer = (int*)pIrp->AssociatedIrp.SystemBuffer;
int * outBuffer = (int *)pIrp->AssociatedIrp.SystemBuffer;
KdPrint(("Enter add_code\n"));
a = *inputBuffer;
b = *(inputBuffer + 1);
KdPrint(("a=%d, b=%d\n", a, b));
r = a + b;
*outBuffer = r;
KdPrint(("a+b=%d\n", r));
info = 4;
break;
}
case sub_code:
{
break;
}
}
}
default:
{
KdPrint(("其它處理"));
break;
}
}
pIrp->IoStatus.Information = info; //設置操作的字節數爲0,這裏無實際意義
pIrp->IoStatus.Status = STATUS_SUCCESS; //返回成功
IoCompleteRequest(pIrp, IO_NO_INCREMENT); //指示完成此IRP
KdPrint(("離開派遣函數\n")); //調試信息
return STATUS_SUCCESS;
}
#pragma INITCODE
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING reg_path)
{
KdPrint(("驅動加載成功\n"));
pDriverObject->MajorFunction[IRP_MJ_CREATE] = MyDispatchRoutine;
pDriverObject->MajorFunction[IRP_MJ_CLOSE] = MyDispatchRoutine;
pDriverObject->MajorFunction[IRP_MJ_READ] = MyDispatchRoutine;
pDriverObject->MajorFunction[IRP_MJ_WRITE] = MyDispatchRoutine;
pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = MyDispatchRoutine;
CreateMyDevice(pDriverObject);
pDriverObject->DriverUnload = DriverUnload;
return STATUS_SUCCESS;
}
在測試機中用instdrv驅動加載工具加載並啓動驅動程序:
在cmd下運行exe程序,輸入a b,計算a+b,運行結果如下: