当前位置:
文档之家› Windows982000驱动程序编写方法
Windows982000驱动程序编写方法
41
微计算机系统
微计算机系统 void doWrite(int n) // 向驱动程序中写数据 { char *buf; ULONG nWritten; int i, j; buf = (char *) malloc(n); if (buf == NULL) { printf("Failed to allocate buffer for write"); Exit(1); } // start with the mod26 letter of the number of bytes to write j = (n % 26); // load buffer with dummy data (abcdefg...) for (i=0; i<n; i++, j=(j + 1)%26) { buf[i] = 'a' + j; } 42
微计算机系统
驱动程序装载 器,可动态调 用驱动程序
28
微计算机系统
驱动程序监视器界面
29
微计算机系统
驱动程序装载器界面
30
微计算机系统
31
微计算机系统
32
微计算机系统
33
微计算机系统
34
微计算机系统
35
微计算机系统
36
2)完成应用程序和驱动程序之间的信息交换
微计算机系统
下面我们来修改有关代码,以便增加驱动程序和应 用程序之间相互通信的内容。需要增加的内容包括: a. 使用Read和Write方式分别从驱动程序读入字符和 向驱动程序写字符。 b. 使用IO控制代码方式分别从驱动程序读入字符和 向驱动程序写字符。 c. 使用IO控制代码方式向驱动程序写字符串再从驱动 程序中读出该字符串,并返回反馈串信息。 注意:程序中暗红色显示的部分是我们添加或修改 过的语句,其他是DriverWorks自动生成的。语句中 “t<< xxxxx”这样的语句是向调试软件输出信息,该 信息可以再DriverMonitor或其他调试监视器中看到。
public:
DEVMEMBER_DISPATCHERS virtual NTSTATUS OnStartDevice(KIrp I); virtual NTSTATUS OnStopDevice(KIrp I); virtual NTSTATUS OnRemoveDevice(KIrp I); virtual NTSTATUS DefaultPnp(KIrp I); virtual NTSTATUS DefaultPower(KIrp I); virtual NTSTATUS OnDevicePowerUp(KIrp I); virtual NTSTATUS OnDeviceSleep(KIrp I); void SerialRead(KIrp I); void SerialWrite(KIrp I);
23
下面我们讲解编译、执行和调试这个驱动程序。
先编译驱动程 序工程
微计算机系统
在VC的集成环境中
24
微计算机系统
25
微计算机系统
再编译测试应 用程序工程
26
微计算机系统
27
下面使用DriverStudio带的工具加载驱动程序和查看 调试信息。 驱动程序监视,可实 时看到驱动程序发出 的调试输出语句
40
printf("%d bytes read from device (%d requested).\n", nRead, nRead); // Print what was read while(i < nRead) { 这几句删除 // j = min((i+26),n); // for(; i < j; i++) // { // printf("%c, ", buf[i]); // } // printf("\n"); printf("%c, ",buf[i++]); } printf("\n"); free(buf); }
17
微计算机系统
驱动类 设备类
18
微计算机系统
驱动类文件 设备类文件
驱动安装 指导文件 测试用的控制 台程序文件
19
微计算机系统
此时已经具备了一个驱动程序以及做测试 用的应用程序的基本框架,我们可以在VC集 成环境下修改有关程序,增加相关的具体操 作代码,然后就可以编译和调试了。
20
微计算机系统
该驱动程序框架包含了几个最基本的类,这些类是:
class Sample : public KDriver // 驱动程序类,用于初始化驱动程序 { SAFE_DESTRUCTORS public: // 以下成员函数注意和WDM中有关例程联系起来看 virtual NTSTATUS DriverEntry(PUNICODE_STRING RegistryPath); virtual NTSTATUS AddDevice(PDEVICE_OBJECT Pdo); void LoadRegistryParameters(KRegistryKey &Params); int m_Unit;
6
微计算机系统
驱动类 名称 驱动类 文件名
7
微计算机系统
选择需要 处理的消 息句柄
8
微计算机系统
9
微计算机系统
10
微计算机系统
11
微计算机系统
添加和应用程 序之间通信的 控制代码
12
微计算机系统
13
微计算机系统
14
微计算机系统
测试用应用 程序名称
15
微计算机系统
16
微计算机系统
Test_Sample.cpp
微计算机系统
void doRead(int n) // 从驱动程序中读数据 { char *buf; ULONG nRead; int i, j; buf = (char *) malloc(n); if (buf == NULL) { printf("Failed to allocate buffer for read"); Exit(1); } // Read data from driver printf("Reading from device - "); ReadFile(hDevice, buf, n, &nRead, NULL); // 参数分别是设备句柄、输入缓冲地址、缓冲大小(字 节数)、实际读的数据字节数、覆盖结构指针。
22
微计算机系统 NTSTATUS SAMPLE_IOCTL_Read_Handler(KIrp I); NTSTATUS SAMPLE_IOCTL_Write_Handler(KIrp I); NTSTATUS SAMPLE_IOCTL_ReadWrite_Handler(KIrp I); #ifdef _COMMENT_ONLY virtual NTSTATUS Create(KIrp I); virtual NTSTATUS Close(KIrp I); virtual NTSTATUS DeviceControl(KIrp I); virtual NTSTATUS SystemControl(KIrp I); virtual NTSTATUS Read(KIrp I); virtual NTSTATUS Write(KIrp I); #endif // Member Data protected: // Unit number for this device (0-9) ULONG m_Unit; KPnpLowerDevice m_Lower; SampleDevice_DriverManagedQueue m_DriverManagedQueue; // TODO: Create additional driver managed queues. These might be // of the same class (SampleDevice_DriverManagedQueue), // or you might choose to derive another class. };
37
a. 使用Read和Write方式分别读写 SampleDevice.cpp
微计算机系统
void SampleDevice::SerialRead(KIrp I) { t << "Entering SampleDevice::SerialRead, " << I << EOL; NTSTATUS status = STATUS_SUCCESS; PUCHAR pBuffer = (PUCHAR) I.BufferedReadDest();//取得返回数据 BUFF的指针 ULONG dwTotalSize = I.ReadSize(CURRENT); // Requested read size char buff[512]; int n =512, j = (n % 26); for (int i=0; i<n; i++, j=(j + 1)%26) { buff[i] = 'a' + j; } buff[dwTotalSize]=‘\0’; //指定串尾 strcpy((char *)pBuffer,buff); // 把给应用程序的数据拷贝给返回BUFF t << “The string you will read is \”“ << buff << ”\“” << EOL; // 输出调试信息 ULONG dwBytesRead = strlen(buff); // Count of bytes read rmation() = dwBytesRead; // 返回给应用程序的信息的字节个数 I.Status() = status; m_DriverManagedQueue.PnpNextIrp(I); }