ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

Windows驱动开发学习

2022-05-31 21:34:44  阅读:129  来源: 互联网

标签:status uLength Windows OBJECT 学习 NTSTATUS 驱动 pDriver pirp


  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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有