关闭

Windows下C语言操作硬件设备的方法

标签: windows系统编程windows硬件操作Windows驱动操作设备驱动检验
942人阅读 评论(2) 收藏 举报
分类:

本文作者:Fezl

本文原地址:http://blog.csdn.net/u010147522/article/details/49912221



之前都是在linux下操作硬件设备,open、read、write、ioctl,相当方便。

最近要检测windows的驱动程序有没有问题,于是得写个简单的程序测试一下设备的ioctl功能。


说一下windows下操作设备的大体方法:

1. 用设备的GUID来获取设备的路径path

2. 用设备路径来打开设备,获得HANDLE

3. 用HANDLE进行ioctl


大体思路跟Linux差不太多。贴上代码


#include <stdio.h>
#include <objbase.h>
#include <WinBase.h>
#include <SetupAPI.h>	//setupapi.lib
#include "public.h"

#define INTERFACE_DETAIL_SIZE   (1024)

int main()
{
	HANDLE hDevice = NULL;
	HDEVINFO hDevInfo = NULL;
	PSP_DEVICE_INTERFACE_DETAIL_DATA pDetail = NULL;
	GUID guid = {0x57415445, 0x5254, 0x454b, 0x44, 0x52, 0x49, 0x56, 0x45, 0x52, 0x43, 0x24};
	INT nCount, i;
	BOOL bResult;
	CHAR devPath[MAX_PATH];
	SP_DEVICE_INTERFACE_DATA ifdata;
	DWORD outBuffer[512] = { 0 };
	DWORD inBuffer[512];
	DWORD returnBytes = 0;


	memset(inBuffer, 1, 512);
	hDevInfo = SetupDiGetClassDevs(
		&guid, 
		NULL, 
		NULL, 
		DIGCF_PRESENT | DIGCF_DEVICEINTERFACE
		);
	if (hDevInfo == INVALID_HANDLE_VALUE)
	{
		printf("Error: SetupDigetClassDevs .\n");
		return -1;
	}
	printf("OK --- SetupDiGetClassDevs.\n");
 
	// 申请设备接口数据空间   
	pDetail = (PSP_DEVICE_INTERFACE_DETAIL_DATA)GlobalAlloc(LMEM_ZEROINIT, INTERFACE_DETAIL_SIZE);

	pDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

	nCount = 0;
	bResult = TRUE;

	// 设备序号=0,1,2... 逐一测试设备接口,到失败为止   
	while (bResult)
	{
		ifdata.cbSize = sizeof(ifdata);

		// 枚举符合该GUID的设备接口   
		bResult = SetupDiEnumDeviceInterfaces(
			hDevInfo,            // 设备信息集句柄   
			NULL,                   // 不需额外的设备描述   
			&guid,                 // GUID   
			(ULONG)nCount,          // 设备信息集里的设备序号   
			&ifdata);               // 设备接口信息   
		
		if (bResult)
		{
			// 取得该设备接口的细节(设备路径)   
			bResult = SetupDiGetInterfaceDeviceDetail(
				hDevInfo,            // 设备信息集句柄   
				&ifdata,                // 设备接口信息   
				pDetail,                // 设备接口细节(设备路径)   
				INTERFACE_DETAIL_SIZE,  // 输出缓冲区大小   
				NULL,                   // 不需计算输出缓冲区大小(直接用设定值)   
				NULL);                  // 不需额外的设备描述   

			if (bResult)
			{
				strcpy(devPath, pDetail->DevicePath);
				printf("lenth = %d\nDevicePath: %s\n\n", strlen(devPath), devPath);
				nCount++;
			}
		}
		else
		{
			printf("error: %d\n", GetLastError());
		}
	}

	hDevice = CreateFile(
		devPath,
		GENERIC_READ | GENERIC_WRITE,
		0,
		NULL,
		OPEN_EXISTING,
		0,
		NULL
		);
	if (hDevice == INVALID_HANDLE_VALUE)
	{
		printf("Error: CreateFile. code = %d\n", GetLastError);
		return -2;
	}
	printf("OK --- CreateFile.\n");


	printf("Bytes = %d,  outBuffer; %s\n", returnBytes, outBuffer);


	bResult = DeviceIoControl(
		hDevice,
		WTDRIVER_MEMORY_WRITE_BAR1,
		inBuffer, 256,
		NULL, 0,
		&returnBytes,
		NULL
		);
	if (!bResult){
		printf("Error: DeviceIoControl.");
		return -3;
	}

	bResult = DeviceIoControl(
		hDevice,<span style="white-space:pre">			</span>//设备句柄
		WTDRIVER_MEMORY_READ_BAR1,<span style="white-space:pre">	</span>//读BAR1
		NULL, 0,
		outBuffer, 256,<span style="white-space:pre">			</span>//读在outBuffer里,读256个字节
		&returnBytes,<span style="white-space:pre">			</span>//实际读取字节数
		NULL
		);
	if (!bResult){
		printf("Error: DeviceIoControl.");
		return -3;
	}

	printf("Bytes = %d\n", returnBytes);
	for (i = 0; i < returnBytes; i++)
	{
		printf("%d: outBuffer: %#x\n", i, outBuffer[i]);
	}

	CloseHandle(hDevice);
	// 释放设备接口数据空间   
	GlobalFree(pDetail);
	// 关闭设备信息集句柄   
	SetupDiDestroyDeviceInfoList(hDevInfo);


	system("pause");
	return 0;
}


其中的publi.h只是我要操作的这个设备特有的头文件。


DeviceIoControl函数中的参数是定义在硬件的驱动程序里的。
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:5859次
    • 积分:144
    • 等级:
    • 排名:千里之外
    • 原创:8篇
    • 转载:1篇
    • 译文:0篇
    • 评论:2条
    文章分类
    最新评论