实战DeviceIoControl 之一:通过API访问设备驱动程序

Q 在NT/2000/XP中,我想用VC编写应用程序访问硬件设备,如获取磁盘参数、读写绝对扇区数据、测试光驱实际速度等,该从哪里入手呢?

A 在NT/2000/XP中,应用程序可以通过API函数DeviceIoControl来实现对设备的访问—获取信息,发送命令,交换数据等。利用该接口函数向指定的设备驱动发送正确的控制码及数据,然后分析它的响应,就可以达到我们的目的。

DeviceIoControl的函数原型为

BOOL DeviceIoControl(
    HANDLE hDevice,              // 设备句柄
    DWORD dwIoControlCode,       // 控制码
    LPVOID lpInBuffer,           // 输入数据缓冲区指针
    DWORD nInBufferSize,         // 输入数据缓冲区长度
    LPVOID lpOutBuffer,          // 输出数据缓冲区指针
    DWORD nOutBufferSize,        // 输出数据缓冲区长度
    LPDWORD lpBytesReturned,     // 输出数据实际长度单元长度
    LPOVERLAPPED lpOverlapped    // 重叠操作结构指针
);

设备句柄用来标识你所访问的设备。

发送不同的控制码,可以调用设备驱动程序的不同类型的功能。在头文件winioctl.h中,预定义的标准设备控制码,都以IOCTL或FSCTL开头。例如,IOCTL_DISK_GET_DRIVE_GEOMETRY是对物理驱动器取结构参数(介质类型、柱面数、每柱面磁道数、每磁道扇区数等)的控制码,FSCTL_LOCK_VOLUME是对逻辑驱动器的卷加锁的控制码。

输入输出数据缓冲区是否需要,是何种结构,以及占多少字节空间,完全由不同设备的不同操作类型决定。在头文件winioctl.h中,已经为标准设备预定义了一些输入输出数据结构。重叠操作结构指针设置为NULL,DeviceIoControl将进行阻塞调用;否则,应在编程时按异步操作设计。

Q 设备句柄是从哪里获得的?

A

  • 0
    点赞
  • 132
    收藏
    觉得还不错? 一键收藏
  • 18
    评论
很抱歉,作为AI语言模型,我无法提供完整的驱动程序代码,但是我可以为您提供一个简单的驱动程序示例,供您参考。 示例代码如下: ```c #include <ntddk.h> // 驱动程序入口函数 NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { UNREFERENCED_PARAMETER(RegistryPath); // 初始化驱动程序对象 DriverObject->DriverUnload = Example_Unload; // 注册设备对象 UNICODE_STRING DeviceName; RtlInitUnicodeString(&DeviceName, L"\\Device\\ExampleDevice"); PDEVICE_OBJECT DeviceObject = NULL; NTSTATUS Status = IoCreateDevice(DriverObject, 0, &DeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, &DeviceObject); if (!NT_SUCCESS(Status)) { return Status; } // 注册设备对象处理函数 DriverObject->MajorFunction[IRP_MJ_CREATE] = Example_Create; DriverObject->MajorFunction[IRP_MJ_CLOSE] = Example_Close; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = Example_IoControl; // 设置设备对象的标志 DeviceObject->Flags |= DO_DIRECT_IO; DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; return STATUS_SUCCESS; } // 设备对象创建处理函数 NTSTATUS Example_Create(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { UNREFERENCED_PARAMETER(DeviceObject); Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; } // 设备对象关闭处理函数 NTSTATUS Example_Close(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { UNREFERENCED_PARAMETER(DeviceObject); Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; } // 设备对象IO控制处理函数 NTSTATUS Example_IoControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { UNREFERENCED_PARAMETER(DeviceObject); PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp); ULONG ControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode; switch (ControlCode) { case IOCTL_EXAMPLE_SET_DATA: // 处理设置数据的操作 break; case IOCTL_EXAMPLE_GET_DATA: // 处理获取数据的操作 break; default: Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_INVALID_DEVICE_REQUEST; } Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; } // 驱动程序卸载处理函数 VOID Example_Unload(IN PDRIVER_OBJECT DriverObject) { UNICODE_STRING DeviceName; RtlInitUnicodeString(&DeviceName, L"\\Device\\ExampleDevice"); // 删除设备对象 IoDeleteDevice(DriverObject->DeviceObject); // 卸载驱动程序 DriverObject->DriverUnload = NULL; } ``` 该示例驱动程序是一个基本的设备驱动程序,包含设备对象创建、关闭、IO控制等处理函数。您可以根据实际需要进行修改和添加。请注意,驱动程序开发需要熟悉Windows内核编程,同时需要小心谨慎,以避免对系统产生负面影响。建议您参考相关的教材或者网上的资源,以帮助您完成驱动程序的编写。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值