




已阅读5页,还剩6页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
能够保证各个并行的IRP顺序执行,即串行化。很多时候,对设备的操作必须是串行化,驱动程序有必要将并行的请求变成串行的请求,需要用到队列。并行运行(函数执行交织在一起) 如果想一次处理每个IRP,必须采用队列将处理串行化。采用“先来先服务”原则cppview plaincopyprint?1. typedefstruct_KDEVICE_QUEUE/IRP队列来实现串行2. CSHORTType;3. CSHORTSize;4. LIST_ENTRYdevicelisthead;5. KSPIN_LOCKLock;6. BOOLEANBusy;7. KDEVICE_QUEUE,*PKDEVICE_QUEUE,*RESTRICTED_POINTERPRKDEVICE_QUEUE;这个StartIO例程声明在DriverEntry中:pDriverObject-DriverStartIo = HelloDDKStartIO;运行再 DISPATCH_LEVEL 级别,不会被线程所打断。 这个例程 参数类似派遣函数,不敢没有返回值在声明时 加上#pragma LOCKEDCODE示例:在使用StartIO例程时,需要IRP的派遣函数返回挂起状态。调用cppview plaincopyprint?1. VOID2. IoStartPacket(3. INPDEVICE_OBJECTDeviceObject,4. INPIRPIrp,5. INPULONGKeyOPTIONAL,/Ifthisiszero,thepacketisinsertedatthetailofthedevicequeue.6. INPDRIVER_CANCELCancelFunctionOPTIONAL/Specifiestheentrypointforadriver-suppliedCancelroutine.7. );cppview plaincopyprint?1. VOID2. IoStartNextPacket(3. INPDEVICE_OBJECTDeviceObject,4. INBOOLEANCancelable5. );cppview plaincopyprint?1. BOOLEAN2. KeRemoveEntryDeviceQueue(/从设备队列中将该IRP抽取出来3. INPKDEVICE_QUEUEDeviceQueue,4. INPKDEVICE_QUEUE_ENTRYDeviceQueueEntry5. );StartIO例程 运行再DISPATCH_LEVEL级别,因此不能使用分页内存,否则会引起页故障,从而导致系统崩溃下面示例:应用程序示例:cppview plaincopyprint?1. #include2. #include3. #include4. 5. UINTWINAPIThread(LPVOIDcontext)6. 7. printf(EnterThreadn);8. /等待5秒9. OVERLAPPEDoverlap=0;10. overlap.hEvent=CreateEvent(NULL,FALSE,FALSE,NULL);11. UCHARbuffer10;12. ULONGulRead;13. 14. BOOLbRead=ReadFile(*(PHANDLE)context,buffer,10,&ulRead,&overlap);15. 16. /可以试验取消例程17. CancelIo(*(PHANDLE)context);/如果不注释这一句那么会正常执行两个HelloDDKRead18. 19. WaitForSingleObject(overlap.hEvent,INFINITE);20. printf(读取完毕!n);21. return0;22. 23. intmain()24. 25. HANDLEhDevice=26. CreateFile(.HelloDDK,27. GENERIC_READ|GENERIC_WRITE,28. FILE_SHARE_READ,29. NULL,30. OPEN_EXISTING,31. FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,/此处设置FILE_FLAG_OVERLAPPED32. NULL);33. if(hDevice=INVALID_HANDLE_VALUE)34. 35. printf(OpenDevicefailed!);36. return1;37. 38. HANDLEhThread2;39. hThread0=(HANDLE)_beginthreadex(NULL,0,Thread,&hDevice,0,NULL);40. hThread1=(HANDLE)_beginthreadex(NULL,0,Thread,&hDevice,0,NULL);41. 42. /主线程等待两个子线程结束43. WaitForMultipleObjects(2,hThread,TRUE,INFINITE);44. 45. printf(两个子线程结束!n);46. /创建IRP_MJ_CLEANUPIRP47. CloseHandle(hDevice);48. 49. return0;50. 驱动代码:cppview plaincopyprint?1. #includeDriver.h2. 3. #pragmaLOCKEDCODE4. VOID5. HelloDDKStartIO(6. INPDEVICE_OBJECTDeviceObject,7. INPIRPIrp8. )9. 10. KIRQLoldirql;11. KdPrint(EnterHelloDDKStartIOn);12. 13. /获取cancel自旋锁14. IoAcquireCancelSpinLock(&oldirql);15. if(Irp!=DeviceObject-CurrentIrp|Irp-Cancel)16. 17. /如果当前有正在处理的IRP,则简单的入队列,并直接返回18. /入队列的工作由系统完成,在StartIO中不用负责19. KdPrint(如果当前有正在处理的IRP,则简单的入队列,并直接返回n);20. IoReleaseCancelSpinLock(oldirql);21. KdPrint(LeaveHelloDDKStartIOn);22. return;23. else24. 25. /由于正在处理该IRP,所以不允许调用取消例程26. /因此将此IRP的取消例程设置为NULL27. KdPrint(由于正在处理该IRP,所以不允许调用取消例程n);28. IoSetCancelRoutine(Irp,NULL);29. IoReleaseCancelSpinLock(oldirql);30. 31. 32. KEVENTevent;33. KeInitializeEvent(&event,NotificationEvent,FALSE);34. 35. /等3秒36. KdPrint(等3秒n);37. LARGE_INTEGERtimeout;38. timeout.QuadPart=-3*1000*1000*10;39. 40. /定义一个3秒的延时,主要是为了模拟该IRP操作需要大概3秒左右时间41. KeWaitForSingleObject(&event,Executive,KernelMode,FALSE,&timeout);42. /SpecifiesaBooleanvaluethatisTRUEifthewaitisalertable43. 44. KdPrint(等3秒结束n);45. 46. Irp-IoStatus.Status=STATUS_SUCCESS;47. Irp-IoStatus.Information=0;/nobytesxfered48. IoCompleteRequest(Irp,IO_NO_INCREMENT);49. 50. 51. /在队列中读取一个IRP,并进行StartIo52. KdPrint(在队列中读取一个IRP,并进行StartIon);53. IoStartNextPacket(DeviceObject,TRUE);54. /1)true获取自旋锁55. /2)删除设备队列56. /3)获取IRP指针57. /4)设置IRP58. /5)true释放自旋锁59. /6)调用StartIo函数(设备对象,IRP)60. 61. KdPrint(LeaveHelloDDKStartIOn);62. 63. /*64. *函数名称:DriverEntry65. *功能描述:初始化驱动程序,定位和申请硬件资源,创建内核对象66. *参数列表:67. pDriverObject:从I/O管理器中传进来的驱动对象68. pRegistryPath:驱动程序在注册表的中的路径69. *返回值:返回初始化驱动状态70. */71. #pragmaINITCODE72. externCNTSTATUSDriverEntry(73. INPDRIVER_OBJECTpDriverObject,74. INPUNICODE_STRINGpRegistryPath)75. 76. NTSTATUSstatus;77. KdPrint(EnterDriverEntryn);78. 79. /设置卸载函数80. pDriverObject-DriverUnload=HelloDDKUnload;81. 82. /设置派遣函数83. pDriverObject-MajorFunctionIRP_MJ_CREATE=HelloDDKDispatchRoutin;84. pDriverObject-MajorFunctionIRP_MJ_CLOSE=HelloDDKDispatchRoutin;85. pDriverObject-MajorFunctionIRP_MJ_WRITE=HelloDDKDispatchRoutin;86. pDriverObject-MajorFunctionIRP_MJ_READ=HelloDDKRead;87. pDriverObject-MajorFunctionIRP_MJ_CLEANUP=HelloDDKDispatchRoutin;88. pDriverObject-MajorFunctionIRP_MJ_DEVICE_CONTROL=HelloDDKDispatchRoutin;89. pDriverObject-MajorFunctionIRP_MJ_SET_INFORMATION=HelloDDKDispatchRoutin;90. pDriverObject-MajorFunctionIRP_MJ_SHUTDOWN=HelloDDKDispatchRoutin;91. pDriverObject-MajorFunctionIRP_MJ_SYSTEM_CONTROL=HelloDDKDispatchRoutin;92. 93. /设置StartIO例程94. pDriverObject-DriverStartIo=HelloDDKStartIO;95. 96. /创建驱动设备对象97. status=CreateDevice(pDriverObject);98. 99. KdPrint(LeaveDriverEntryn);100. returnstatus;101. 102. /*103. *函数名称:CreateDevice104. *功能描述:初始化设备对象105. *参数列表:106. pDriverObject:从I/O管理器中传进来的驱动对象107. *返回值:返回初始化状态108. */109. #pragmaINITCODE110. NTSTATUSCreateDevice(111. INPDRIVER_OBJECTpDriverObject)112. 113. NTSTATUSstatus;114. PDEVICE_OBJECTpDevObj;115. PDEVICE_EXTENSIONpDevExt;116. 117. /创建设备名称118. UNICODE_STRINGdevName;119. RtlInitUnicodeString(&devName,LDeviceMyDDKDevice);120. 121. /创建设备122. status=IoCreateDevice(pDriverObject,123. sizeof(DEVICE_EXTENSION),124. &(UNICODE_STRING)devName,125. FILE_DEVICE_UNKNOWN,126. 0,TRUE,127. &pDevObj);128. if(!NT_SUCCESS(status)129. returnstatus;130. 131. pDevObj-Flags|=DO_BUFFERED_IO;132. pDevExt=(PDEVICE_EXTENSION)pDevObj-DeviceExtension;133. pDevExt-pDevice=pDevObj;134. pDevExt-ustrDeviceName=devName;135. 136. /创建符号链接137. UNICODE_STRINGsymLinkName;138. RtlInitUnicodeString(&symLinkName,L?HelloDDK);139. pDevExt-ustrSymLinkName=symLinkName;140. status=IoCreateSymbolicLink(&symLinkName,&devName);141. if(!NT_SUCCESS(status)142. 143. IoDeleteDevice(pDevObj);144. returnstatus;145. 146. returnSTATUS_SUCCESS;147. 148. /*149. *函数名称:HelloDDKUnload150. *功能描述:负责驱动程序的卸载操作151. *参数列表:152. pDriverObject:驱动对象153. *返回值:返回状态154. */155. #pragmaPAGEDCODE156. VOIDHelloDDKUnload(INPDRIVER_OBJECTpDriverObject)157. 158. PDEVICE_OBJECTpNextObj;159. KdPrint(EnterDriverUnloadn);160. pNextObj=pDriverObject-DeviceObject;161. while(pNextObj!=NULL)162. 163. PDEVICE_EXTENSIONpDevExt=(PDEVICE_EXTENSION)164. pNextObj-DeviceExtension;165. 166. /删除符号链接167. UNICODE_STRINGpLinkName=pDevExt-ustrSymLinkName;168. IoDeleteSymbolicLink(&pLinkName);169. 170. pNextObj=pNextObj-NextDevice;171. IoDeleteDevice(pDevExt-pDevice);172. 173. 174. /*175. *函数名称:HelloDDKDispatchRoutin176. *功能描述:对读IRP进行处理177. *参数列表:178. pDevObj:功能设备对象179. pIrp:从IO请求包180. *返回值:返回状态181. */182. #pragmaPAGEDCODE183. NTSTATUSHelloDDKDispatchRoutin(INPDEVICE_OBJECTpDevObj,184. INPIRPpIrp)185. 186. KdPrint(EnterHelloDDKDispatchRoutinn);187. PIO_STACK_LOCATIONstack=IoGetCurrentIrpStackLocation(pIrp);188. /建立一个字符串数组与IRP类型对应起来189. staticchar*irpname=190. 191. IRP_MJ_CREATE,192. IRP_MJ_CREATE_NAMED_PIPE,193. IRP_MJ_CLOSE,194. IRP_MJ_READ,195. IRP_MJ_WRITE,196. IRP_MJ_QUERY_INFORMATION,197. IRP_MJ_SET_INFORMATION,198. IRP_MJ_QUERY_EA,199. IRP_MJ_SET_EA,200. IRP_MJ_FLUSH_BUFFERS,201. IRP_MJ_QUERY_VOLUME_INFORMATION,202. IRP_MJ_SET_VOLUME_INFORMATION,203. IRP_MJ_DIRECTORY_CONTROL,204. IRP_MJ_FILE_SYSTEM_CONTROL,205. IRP_MJ_DEVICE_CONTROL,206. IRP_MJ_INTERNAL_DEVICE_CONTROL,207. IRP_MJ_SHUTDOWN,208. IRP_MJ_LOCK_CONTROL,209. IRP_MJ_CLEANUP,210. IRP_MJ_CREATE_MAILSLOT,211. IRP_MJ_QUERY_SECURITY,212. IRP_MJ_SET_SECURITY,213. IRP_MJ_POWER,214. IRP_MJ_SYSTEM_CONTROL,215. IRP_MJ_DEVICE_CHANGE,216. IRP_MJ_QUERY_QUOTA,217. IRP_MJ_SET_QUOTA,218. IRP_MJ_PNP,219. ;220. UCHARtype=stack-MajorFunction;221. if(type=arraysize(irpname)222. KdPrint(-UnknownIRP,majortype%Xn,type);223. else224. KdPrint(t%sn,irpnametype);225. 226. 227. /对一般IRP的简单操作,后面会介绍对IRP更复杂的操作228. NTSTATUSstatus=STATUS_SUCCESS;229. /完成IRP230. pIrp-IoStatus.Status=status;231. pIrp-IoStatus.Information=0;/bytesxfered232. IoCompleteRequest(pIrp,IO_NO_INCREMENT);233. 234. KdPrint(LeaveHelloDDKDispatchRoutinn);235. 236. returnstatus;237. 238. VOID239. OnCancelIRP(/如果在应用程序中调用CancelIo取消例程那么就会执行OnCancelIRP240. INPDEVICE_OBJECTDeviceObject,241. INPIRPIrp242. )243. 244. KdPrint(EnterCancelReadIRPn);245. 246. if(Irp=DeviceObject-CurrentIrp)247. 248. /表明当前正在改由StartIo处理249. KdPrint(当前正在改由StartIo处理n);250. /但StartIo并没有获取cancel自旋锁之前251. /这时候需要252. KIRQLoldirql=Irp-CancelIrql;253. 254. /释放Cancel自旋锁255. IoReleaseCancelSpinLock(Irp-CancelIrql);256. 257. IoStartNextPacket(DeviceObje
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年新能源汽车自动驾驶技术法规与道路安全监管报告
- 2025年工业污染场地修复技术成本效益分析与优化方案报告
- 2025年教育行业质量评估与认证体系教育评价改革与创新实践报告
- 在陕西考古博物馆的试题及答案
- 2025年农业科技成果转化与农业人才培养案例报告
- 2025年新能源产业专利布局与技术升级趋势报告
- 2025年工业互联网平台数字签名技术规范与工业互联网平台设备升级规范标准报告
- 2025-2030工业软件云化迁移阻力与订阅制商业模式验证报告
- 2025-2030工业软件云化转型障碍突破与订阅模式可行性报告
- 2025-2030工业软件云化转型趋势与中小企业渗透策略专项研究报告
- 初三学习策略模板
- 外销合同协议书英文翻译
- 灌区续建配套与节水改造规划报告
- 财务咨询外包协议
- 2023-2024学年上海市杨浦区六年级上学期期中考试语文试卷含详解
- 农行超级柜台业务知识考试题库(含答案)
- 新标准大学英语(第三版)综合教程3(智慧版)课件 Unit6 Path to prosperity
- 3认识你自己-大学生自我意识发展课件
- 中药学全套(完整版)课件
- GB 1886.232-2016食品安全国家标准食品添加剂羧甲基纤维素钠
- 育儿嫂服务合同
评论
0/150
提交评论