reactos操作系统实现(129)
功能驱动将构造请求包,就可以发送到底层总线驱动上。因此需要创建一个IRP,这就需要用IoBuildDeviceIoControlRequest创建一个IO控制码的IRP,用IoCallDriver将URB发送到底层总线驱动上。由于上层驱动无法知道底层驱动是同步还是异步完成的,因此需要做一个判断。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} (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |