应用层的文件句柄传递给 驱动层 完成文件写入

1 驱动程序 编译出64位

#include <ntddk.h>

#define DEVICE_NAME L"\\Device\\MyDevice"

#define SYMBOLIC_LINK_NAME L"\\??\\MyDeviceLink"

#define IOCTL_WRITE_DATA CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)

// 设备扩展结构

typedef struct _DEVICE_EXTENSION {

HANDLE FileHandle; // 保存打开文件的句柄

} DEVICE_EXTENSION, * PDEVICE_EXTENSION;

NTSTATUS DeviceIoControlHandler(PDEVICE_OBJECT DeviceObject, PIRP Irp);

VOID UnloadDriver(PDRIVER_OBJECT DriverObject);

NTSTATUS MyCreateHandler(PDEVICE_OBJECT DeviceObject, PIRP Irp) {

//PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);

// 这里可以添加打开文件的逻辑,比如设置某些设备状态、初始化资源等

UNREFERENCED_PARAMETER(DeviceObject);

DbgPrint("Device opened successfully.\n");

// 设置 IRP 处理结果

Irp->IoStatus.Status = STATUS_SUCCESS;

Irp->IoStatus.Information = 0; // 可以返回的信息数量

IoCompleteRequest(Irp, IO_NO_INCREMENT); // 完成 IRP 请求

return STATUS_SUCCESS;

}

NTSTATUS MyCloseHandler(PDEVICE_OBJECT DeviceObject, PIRP Irp) {

// 这里可以添加关闭文件的逻辑,比如释放资源等

UNREFERENCED_PARAMETER(DeviceObject);

DbgPrint("Device closed successfully.\n");

// 设置 IRP 处理结果

Irp->IoStatus.Status = STATUS_SUCCESS;

Irp->IoStatus.Information = 0;

IoCompleteRequest(Irp, IO_NO_INCREMENT); // 完成 IRP 请求

return STATUS_SUCCESS;

}

// 驱动程序入口函数

NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) {

UNREFERENCED_PARAMETER(RegistryPath);

NTSTATUS status;

UNICODE_STRING deviceName, symbolicLinkName;

// 创建设备名称

RtlInitUnicodeString(&deviceName, DEVICE_NAME);

// 创建设备

PDEVICE_OBJECT deviceObject;

status = IoCreateDevice(DriverObject, sizeof(DEVICE_EXTENSION), &deviceName,

FILE_DEVICE_UNKNOWN, 0, FALSE, &deviceObject);

if (!NT_SUCCESS(status)) {

return status; // 创建设备失败

}

// 创建符号链接指向设备名称

RtlInitUnicodeString(&symbolicLinkName, L"\\DosDevices\\MyDeviceLink");

status = IoCreateSymbolicLink(&symbolicLinkName, &deviceName);

if (NT_SUCCESS(status)) {

DbgPrint("Symbolic link created successfully: %wZ -> %wZ\n", &symbolicLinkName, &deviceName);

}

else {

DbgPrint("Failed to create symbolic link: %08X\n", status);

IoDeleteDevice(deviceObject); // 清理资源

return status;

}

// 设置驱动程序的主要函数指针

DriverObject->MajorFunction[IRP_MJ_CREATE] = MyCreateHandler;

DriverObject->MajorFunction[IRP_MJ_CLOSE] = MyCloseHandler;

DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DeviceIoControlHandler;

// 设置卸载处理函数

DriverObject->DriverUnload = UnloadDriver;

// 初始化设备扩展

PDEVICE_EXTENSION deviceExtension = (PDEVICE_EXTENSION)deviceObject->DeviceExtension;

deviceExtension->FileHandle = NULL; // 初始化文件句柄

return STATUS_SUCCESS;

}

// 在驱动程序卸载时,别忘了删除符号链接

VOID UnloadDriver(PDRIVER_OBJECT DriverObject) {

UNICODE_STRING symbolicLinkName;

RtlInitUnicodeString(&symbolicLinkName, L"\\DosDevices\\MyDeviceLink");

// 删除符号链接

IoDeleteSymbolicLink(&symbolicLinkName);

DbgPrint("Symbolic link deleted: %wZ\n", &symbolicLinkName);

// 删除设备

IoDeleteDevice(DriverObject->DeviceObject);

DbgPrint("Driver unloaded successfully.\n");

}

NTSTATUS DeviceIoControlHandler(PDEVICE_OBJECT DeviceObject, PIRP Irp) {

UNREFERENCED_PARAMETER(DeviceObject);

PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);

NTSTATUS status = STATUS_SUCCESS;

ULONG inputBufferLength = irpStack->Parameters.DeviceIoControl.InputBufferLength;

PVOID inputBuffer = Irp->AssociatedIrp.SystemBuffer;

// 验证输入缓冲区大小

if (inputBufferLength < sizeof(HANDLE) + sizeof(char[256])) {

Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; // 设置 IRP 的状态

Irp->IoStatus.Information = 0; // 设置返回信息字节数

IoCompleteRequest(Irp, IO_NO_INCREMENT); // 完成 IRP,以避免挂起

return STATUS_INVALID_PARAMETER; // 返回错误码

}

// 获取传递的文件句柄和数据

HANDLE fileHandle = *(HANDLE*)inputBuffer; // 假设传递句柄在缓冲区的开始

char* dataBuffer = (char*)((char*)inputBuffer + sizeof(HANDLE)); // 获取数据

IO_STATUS_BLOCK ioStatusBlock;

ULONG bytesWritten = 0;

// 用传递的句柄写入文件

status = ZwWriteFile(fileHandle, NULL, NULL, NULL, &ioStatusBlock,

dataBuffer, (ULONG)strlen(dataBuffer), NULL, NULL);

// 检查写入结果

if (NT_SUCCESS(status)) {

bytesWritten = (ULONG)ioStatusBlock.Information; // 写入的字节数

}

// 完成 IRP

Irp->IoStatus.Status = status;

Irp->IoStatus.Information = bytesWritten; // 可以返回写入的字节数

IoCompleteRequest(Irp, IO_NO_INCREMENT);

return status;

}

2 应用程序 编译出 64位 编译出32为可以体验参数不对的情况 因为HANDLE 在32位 64位长度不一样 保证 C:\\Path 这个文件目录存在

// writefileblock.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。

//

#include <windows.h>

#include <stdio.h>

#define IOCTL_WRITE_DATA CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)

void SendWriteRequest(HANDLE deviceHandle, HANDLE fileHandle, const char* data) {

DWORD bytesReturned;

// 发送 IOCTL 请求,将文件句柄和数据写入内核

struct {

HANDLE hFile; // 文件句柄

char data[256]; // 待写入的数据

} inputBuffer;

inputBuffer.hFile = fileHandle; // 设置文件句柄

strcpy_s(inputBuffer.data, sizeof(inputBuffer.data), data); // 设置数据

BOOL result = DeviceIoControl(deviceHandle,

IOCTL_WRITE_DATA,

&inputBuffer,

sizeof(inputBuffer), // 包括句柄和数据

NULL,

0,

&bytesReturned,

NULL);

if (!result) {

printf("DeviceIoControl failed: %lu\n", GetLastError());

}

else {

printf("Data written successfully!\n");

}

}

int main() {

// 打开设备(这里需要替换为你的设备名称)

HANDLE deviceHandle = CreateFile(L"\\\\.\\MyDeviceLink",

GENERIC_WRITE,

0,

NULL,

OPEN_EXISTING,

FILE_ATTRIBUTE_NORMAL,

NULL);

if (deviceHandle == INVALID_HANDLE_VALUE) {

printf("Failed to open device: %lu\n", GetLastError());

return 1;

}

// 打开文件并获取句柄

HANDLE fileHandle = CreateFile(L"C:\\Path\\YourFile.txt",

GENERIC_WRITE,

0,

NULL,

OPEN_ALWAYS,

FILE_ATTRIBUTE_NORMAL,

NULL);

if (fileHandle == INVALID_HANDLE_VALUE) {

printf("Failed to open file: %lu\n", GetLastError());

CloseHandle(deviceHandle);

return 1;

}

const char* dataToWrite = "Hello, Kernel!";

SendWriteRequest(deviceHandle, fileHandle, dataToWrite);

// 关闭文件和设备

CloseHandle(fileHandle);

CloseHandle(deviceHandle);

return 0;

}

相关推荐
染指111010 天前
28.实现MDL驱动读写-Windows驱动
windows·驱动开发·驱动·mdl
云卓SKYDROID19 天前
无人机舵机驱动模块技术解析
无人机·驱动·知识科普·高科技·云卓科技
少年、潜行23 天前
F1C100/200S学习笔记(3)-- 裸机开发
linux·笔记·学习·驱动·裸机·f1c200s
才鲸嵌入式1 个月前
STM32 USB协议栈源码分析
stm32·单片机·嵌入式·驱动·usb·硬件·phy
染指11101 个月前
7.Windows驱动-驱动lrp通信
驱动·windows驱动
hszmoran2 个月前
电脑关机重启时显示rundll32 内存不能为read解决方法
电脑·nvidia·驱动
sheepwjl4 个月前
《嵌入式驱动(二):驱动开发基本概念》
arm开发·驱动开发·单片机·嵌入式硬件·imx6ull·驱动·裸机
肖爱Kun4 个月前
LINUX中USB驱动架构—URB请求块
linux·驱动
肖爱Kun4 个月前
LINUX中USB驱动架构—设备驱动
linux·驱动