系统相关
首页 > 系统相关> > Windows驱动开发学习

Windows驱动开发学习

作者:互联网

  1. 链表的使用
    main.h
#pragma once
#include<ntddk.h>
typedef struct _MYDATA {
	LIST_ENTRY ListEntry;
	DWORD64 Id;
	UNICODE_STRING Name;
}MYDATA,*PMYDATA;
extern "C" {
	VOID DrvUnload(IN PDRIVER_OBJECT pDriver);
	NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriver, IN PUNICODE_STRING regPath);
	VOID LinkListTest();
}

main.cpp

#include "main.h"

VOID DrvUnload(IN PDRIVER_OBJECT pDriver)
{
	KdPrint(("驱动卸载成功\n"));
	return VOID();
}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriver, IN PUNICODE_STRING regPath)
{
	NTSTATUS status = STATUS_SUCCESS;
	pDriver->DriverUnload = ::DrvUnload;
	KdPrint(("驱动加载成功\n"));
	::LinkListTest();
	
	return status;
}

VOID LinkListTest()
{
	LIST_ENTRY ListHead;
	InitializeListHead(&ListHead);

	for (DWORD64 i = 0; i < 10; i++)
	{
		PMYDATA pData = (PMYDATA)ExAllocatePool(PagedPool, sizeof(MYDATA));
		pData->Id = i;
		RtlInitUnicodeString(&pData->Name, L"测试名称");
		InsertHeadList(&ListHead, &pData->ListEntry);
	}
	KdPrint(("链表添加成功\n"));
	
	while (!::IsListEmpty(&ListHead))
	{
		PMYDATA pData = (PMYDATA)CONTAINING_RECORD((PMYDATA)::RemoveHeadList(&ListHead), MYDATA, ListEntry);
		KdPrint(("ID:%lld Name:%wZ\n", pData->Id, &pData->Name));
		ExFreePool(pData); //释放空间
	}
	
}
  1. 设备缓冲区读写方式
    main.h
#pragma once
#include<ntddk.h>
#include<initguid.h>
constexpr USHORT DEVICE_NAME[] = L"\\Device\BufferIoTestDevice";
constexpr USHORT SYMBOL_NAME[] = L"\\??\\BufferIoTestDevice";
extern "C" {
	VOID Unload(IN PDRIVER_OBJECT pDriver);
	NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriver, IN PUNICODE_STRING regPath);
	NTSTATUS DispatchDefaultRoutine(PDEVICE_OBJECT pDevice, PIRP pirp);
	NTSTATUS DispatchWrite(PDEVICE_OBJECT pDevice, PIRP pirp);
	NTSTATUS DispatchRead(PDEVICE_OBJECT pDevice, PIRP pirp);
}

main.cpp

#include "main.h"

VOID Unload(IN PDRIVER_OBJECT pDriver)
{
    if (pDriver->DeviceObject)
    {
        IoDeleteDevice(pDriver->DeviceObject);
        UNICODE_STRING SymbolName = RTL_CONSTANT_STRING(SYMBOL_NAME);
        NTSTATUS status = STATUS_SUCCESS;
        status = IoDeleteSymbolicLink(&SymbolName);
        if (!NT_SUCCESS(status))
        {
            KdPrint(("符号链接删除失败!%X\n", status));
        }
    }
    KdPrint(("驱动卸载\n"));
    return VOID();
}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriver, IN PUNICODE_STRING regPath)
{
    NTSTATUS status = STATUS_SUCCESS;
    UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(DEVICE_NAME); //设备名称
    UNICODE_STRING SymbolName = RTL_CONSTANT_STRING(SYMBOL_NAME); //符号名称
    PDEVICE_OBJECT pDevice = nullptr;
    pDriver->DriverUnload = ::Unload;
    status = ::IoCreateDevice(pDriver, NULL, &DeviceName, FILE_DEVICE_UNKNOWN, NULL, TRUE, &pDevice);
    if (!NT_SUCCESS(status))
    {
        KdPrint(("驱动设备创建失败!%X\n", status));
        pDriver->DriverUnload(pDriver);
        return status;
    }
    status = ::IoCreateSymbolicLink(&SymbolName, &DeviceName); //创建符号链接
    if (!NT_SUCCESS(status))
    {
        KdPrint(("符号链接创建失败!%X\n", status));
        pDriver->DriverUnload(pDriver);
        return status;
    }
    pDevice->Flags &= ~DO_DEVICE_INITIALIZING;
    //设置设备缓冲区读写
    pDevice->Flags |= DO_BUFFERED_IO;
    for (INT i = 0; i < IRP_MJ_MAXIMUM_FUNCTION + 1; i++)
    {
        pDriver->MajorFunction[i] = ::DispatchDefaultRoutine;
    }
    pDriver->MajorFunction[IRP_MJ_WRITE] = ::DispatchWrite;
    pDriver->MajorFunction[IRP_MJ_READ] = ::DispatchRead;
    KdPrint(("驱动加载成功\n"));
    return status;
}
//默认的分发函数,什么都不做
NTSTATUS DispatchDefaultRoutine(PDEVICE_OBJECT pDevice, PIRP pirp)
{
    pirp->IoStatus.Information = 0;
    pirp->IoStatus.Status = STATUS_SUCCESS;
    IoCompleteRequest(pirp, IO_NO_INCREMENT);
    return NTSTATUS();
}
//写
NTSTATUS DispatchWrite(PDEVICE_OBJECT pDevice, PIRP pirp)
{
    NTSTATUS status = STATUS_SUCCESS;
    ULONG uLength = 0;
    PIO_STACK_LOCATION pStack = ::IoGetCurrentIrpStackLocation(pirp);
    __try
    {
        uLength = pStack->Parameters.Write.Length;
        if (uLength > 1)
        {
            KdPrint(("%s\n", (PCHAR)pirp->AssociatedIrp.SystemBuffer));
        }
        else
        {
            status = STATUS_INVALID_PARAMETER;
            uLength = 0;
        }
    }
    __except (EXCEPTION_EXECUTE_HANDLER)
    {
        status = GetExceptionCode();
        uLength = 0;
    }
    pirp->IoStatus.Information = uLength;
    pirp->IoStatus.Status = status;
    IoCompleteRequest(pirp, IO_NO_INCREMENT);
    return status;
}

NTSTATUS DispatchRead(PDEVICE_OBJECT pDevice, PIRP pirp)
{
    NTSTATUS status = STATUS_SUCCESS;
    PIO_STACK_LOCATION pStack = ::IoGetCurrentIrpStackLocation(pirp);
    ULONG uLength = 0;
    CHAR Buffer[] = "内核很好";
    __try
    {
        uLength = pStack->Parameters.Read.Length;
        if (uLength > sizeof(Buffer))
        {
            RtlCopyMemory(pirp->AssociatedIrp.SystemBuffer, Buffer, sizeof(Buffer));
        }
        else
        {
            status = STATUS_INVALID_PARAMETER;
            uLength = 0;
        }
    }
    __except (EXCEPTION_EXECUTE_HANDLER)
    {
        status = GetExceptionCode();
        uLength = 0;
    }
    pirp->IoStatus.Information = uLength;
    pirp->IoStatus.Status = status;
    IoCompleteRequest(pirp, IO_NO_INCREMENT);
    return status;
}

用户层应用


#include <iostream>
#include<Windows.h>
using namespace std;

int main()
{
    //打开符号链接
    HANDLE hDevice = ::CreateFile(L"\\\\.\\BufferIoTestDevice", GENERIC_ALL,
        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hDevice == INVALID_HANDLE_VALUE)
    {
        cout << "设备打开失败" << endl;
        return 1;
    }
    CHAR WriteBuffer[] = "3环呼叫";
    DWORD dwWriteLength = 0;
    BOOL res = ::WriteFile(hDevice, WriteBuffer, sizeof(WriteBuffer), &dwWriteLength, NULL);
    CHAR ReadBuffer[1024] = { 0 };
    DWORD dwReadLength = 0;
    res = ::ReadFile(hDevice, ReadBuffer, sizeof(ReadBuffer), &dwReadLength, NULL);
    if (res)
    {
        cout << "读取长度:" << dwReadLength << "  内容:" << ReadBuffer << endl;
    }
    else
    {
        cout << "读取内容失败:" << ::GetLastError() << endl;
    }
    ::getchar();
    return 0;
}

标签:status,uLength,Windows,OBJECT,学习,NTSTATUS,驱动,pDriver,pirp
来源: https://www.cnblogs.com/zzr-stdio/p/16332324.html