reactos操作系统实现(129)

功能驱动将构造请求包,就可以发送到底层总线驱动上。因此需要创建一个IRP,这就需要用IoBuildDeviceIoControlRequest创建一个IO控制码的IRP,用IoCallDriverURB发送到底层总线驱动上。由于上层驱动无法知道底层驱动是同步还是异步完成的,因此需要做一个判断。if语句判断当异步完成IRP时,用事件等待总线驱动完成这个IRP

#001 NTSTATUS

#002 VfatBlockDeviceIoControl (IN PDEVICE_OBJECT DeviceObject,

#003 IN ULONG CtlCode,

#004 IN PVOID InputBuffer OPTIONAL,

#005 IN ULONG InputBufferSize,

#006 IN OUT PVOID OutputBuffer OPTIONAL,

#007 IN OUT PULONG OutputBufferSize,

#008 IN BOOLEAN Override)

#009 {

#010 PIO_STACK_LOCATION Stack;

#011 KEVENT Event;

#012 PIRP Irp;

#013 IO_STATUS_BLOCK IoStatus;

#014 NTSTATUS Status;

#015

#016 DPRINT("VfatBlockDeviceIoControl(DeviceObject %p,CtlCode %x,"

#017 "InputBuffer %p,InputBufferSize %x,OutputBuffer %p,"

#018 "OutputBufferSize %p (%x)/n",DeviceObject,CtlCode,

#019 InputBuffer,InputBufferSize,OutputBuffer,OutputBufferSize,

#020 OutputBufferSize ? *OutputBufferSize : 0);

#021

初始化通知的事件。

#022 KeInitializeEvent (&Event,NotificationEvent,FALSE);

#023

#024 DPRINT("Building device I/O control request .../n");

创建控制码相关的IRP包。

#025 Irp = IoBuildDeviceIoControlRequest(CtlCode,

#026 DeviceObject,

#027 InputBuffer,

#028 InputBufferSize,

#029 OutputBuffer,

#030 (OutputBufferSize) ? *OutputBufferSize : 0,

#031 FALSE,

#032 &Event,

#033 &IoStatus);

如果创建IRP包不成功,就直接返回出错。

#034 if (Irp == NULL)

#035 {

#036 DPRINT("IoBuildDeviceIoControlRequest Failed/n");

#037 return STATUS_INSUFFICIENT_RESOURCES;

#038 }

#039

是否需要获取下一层的设备栈。

#040 if (Override)

#041 {

需要获取下一层次的设备栈。

#042 Stack = IoGetNextIrpStackLocation(Irp);

#043 Stack->Flags |= SL_OVERRIDE_VERIFY_VOLUME;

#044 }

#045

#046 DPRINT ("Calling IO Driver... with irp %p/n",Irp);

IRP包发送到下一个设备驱动程序。

#047 Status = IoCallDriver(DeviceObject,Irp);

#048

#049 DPRINT ("Waiting for IO Operation for %p/n",Irp);

如果在阻塞状态,就等待下层驱动程序完成。

#050 if (Status == STATUS_PENDING)

#051 {

#052 DPRINT ("Operation pending/n");

这里就是等前面创建的事件。

#053 KeWaitForSingleObject (&Event,Suspended,KernelMode,FALSE,NULL);

#054 DPRINT ("Getting IO Status... for %p/n",Irp);

#055

#056 Status = IoStatus.Status;

#057 }

#058

返回输出缓冲区的大小。

#059 if (OutputBufferSize)

#060 {

#061 *OutputBufferSize = IoStatus.information;

#062 }

#063

#064 DPRINT("Returning Status %x/n",Status);

#065

#066 return Status;

#067}

相关文章

一、前言 在组件方面react和Vue一样的,核心思想玩的就是组件...
前言: 前段时间学习完react后,刚好就接到公司一个react项目...
前言: 最近收到组长通知我们项目组后面新开的项目准备统一技...
react 中的高阶组件主要是对于 hooks 之前的类组件来说的,如...
我们上一节了解了组件的更新机制,但是只是停留在表层上,例...
我们上一节了解了 react 的虚拟 dom 的格式,如何把虚拟 dom...