专注于互联网--专注于架构

最新标签
网站地图
文章索引
Rss订阅

首页 »编程综合 » reactos:reactos操作系统实现(94) »正文

reactos:reactos操作系统实现(94)

来源: 发布时间:星期一, 2009年9月28日 浏览:0次 评论:0


  现在就来依次分析i8042Create、i8042Cleanup、i8042Close、i8042DeviceControl、i8042InternalDeviceControl和i8042Pnp首先分析i8042Create实现代码如下:

#001  NTSTATUS NTAPI
#002  i8042Create(
#003     IN PDEVICE_OBJECT DeviceObject,
#004     IN PIRP Irp)
#005  {
#006     TRACE_(I8042PRT, "IRP_MJ_CREATE\n");
#007 


  设置IRP状态为成功

#008     Irp->IoStatus.Status = STATUS_SUCCESS;

  返回状态信息为0

#009     Irp->IoStatus.Information = 0;

  IoCompleteRequest来设置当前IRP完成

#010     IoCompleteRequest(Irp, IO_NO_INCREMENT);
#011      STATUS_SUCCESS;
#012  }


  i8042Cleanup实现代码如下:

#001  NTSTATUS NTAPI
#002  i8042Cleanup(
#003     IN PDEVICE_OBJECT DeviceObject,
#004     IN PIRP Irp)
#005  {
#006     TRACE_(I8042PRT, "IRP_MJ_CLEANUP\n");
#007 


  设置IRP状态为成功

#008     Irp->IoStatus.Status = STATUS_SUCCESS;
#009     Irp->IoStatus.Information = 0;


  IoCompleteRequest来设置当前IRP完成

#010     IoCompleteRequest(Irp, IO_NO_INCREMENT);
#011      STATUS_SUCCESS;
#012  }


  i8042Close实现代码如下:

#001  NTSTATUS NTAPI
#002  i8042Close(
#003     IN PDEVICE_OBJECT DeviceObject,
#004     IN PIRP Irp)
#005  {
#006     TRACE_(I8042PRT, "IRP_MJ_CLOSE\n");
#007 


  设置IRP状态为成功

#008     Irp->IoStatus.Status = STATUS_SUCCESS;
#009     Irp->IoStatus.Information = 0;


  IoCompleteRequest来设置当前IRP完成

#010     IoCompleteRequest(Irp, IO_NO_INCREMENT);
#011      STATUS_SUCCESS;
#012  }


  i8042DeviceControl实现代码如下:

#001   NTSTATUS NTAPI
#002  i8042DeviceControl(
#003     IN PDEVICE_OBJECT DeviceObject,
#004     IN PIRP Irp)
#005  {
#006     PFDO_DEVICE_EXTENSION DeviceExtension;
#007     NTSTATUS Status;
#008 
#009     TRACE_(I8042PRT, "i8042DeviceControl(%p %p)\n", DeviceObject, Irp);


  获取设备扩展

#010     DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
#011 


  根设备类型来处理

#012     switch (DeviceExtension->Type)
#013     {


  这里处理键盘类型设备

#014          Keyboard:
#015              i8042KbdDeviceControl(DeviceObject, Irp);
#016             ;
#017         default:
#018              IrpStub(DeviceObject, Irp);
#019     }
#020 
#021      Status;
#022  }


  接着分析i8042KbdDeviceControl实现代码如下:

#001  NTSTATUS NTAPI
#002  i8042KbdDeviceControl(
#003     IN PDEVICE_OBJECT DeviceObject,
#004     IN PIRP Irp)
#005  {
#006     PIO_STACK_LOCATION Stack;
#007     PI8042_KEYBOARD_EXTENSION DeviceExtension;
#008     NTSTATUS Status;
#009 


  获取当前IRP栈指针

#010     Stack = IoGetCurrentIrpStackLocation(Irp);

  设置返回状态信息为0个

#011     Irp->IoStatus.Information = 0;

  获取扩展设备

#012     DeviceExtension = (PI8042_KEYBOARD_EXTENSION)DeviceObject->DeviceExtension;
#013 


  根据IRP栈里参数来获取操作码然后根据操作码作区别处理

#014     switch (Stack->Parameters.DeviceIoControl.IoControlCode)
#015     {


  获取系统大写键状态

#016          IOCTL_GET_SYS_BUTTON_CAPS:
#017         {
#018             /* Part of GUID_DEVICE_SYS_BUTTON erface */
#019             PULONG pCaps;
#020             TRACE_(I8042PRT, "IOCTL_GET_SYS_BUTTON_CAPS\n");
#021 


  如果返回参数内存空间不够4个字节长就返回非法参数

#022              (Stack->Parameters.DeviceIoControl.OutputBufferLength != (ULONG))
#023                 Status = STATUS_INVALID_PARAMETER;
#024             
#025             {


  获取系统保存参数位置

#026                 pCaps = (PULONG)Irp->AssociatedIrp.Buffer;

  把键盘大写状态返回给系统

#027                 *pCaps = DeviceExtension->NewCaps;
#028                 DeviceExtension->ReportedCaps = DeviceExtension->NewCaps;


  设置IRP返回参数长度为4个字节

#029                 Irp->IoStatus.Information = (ULONG);

  设置返回状态为成功

#030                 Status = STATUS_SUCCESS;
#031             }
#032             ;
#033         }


  获取系统按键事件

#034          IOCTL_GET_SYS_BUTTON_EVENT:
#035         {
#036             /* Part of GUID_DEVICE_SYS_BUTTON erface */
#037             PIRP WaitingIrp;
#038             TRACE_(I8042PRT, "IOCTL_GET_SYS_BUTTON_EVENT\n");
#039 


  判断是否可以返回参数如果不可以返回就直接返回出错

#040              (Stack->Parameters.DeviceIoControl.OutputBufferLength != (ULONG))
#041                 Status = STATUS_INVALID_PARAMETER;
#042             
#043             {


  获取电源按键事件

#044                 WaitingIrp = InterlockedCompareExchangePoer(
#045                     &DeviceExtension->PowerIrp,
#046                     Irp,
#047                     NULL);


  已经有个事件IRP在等待中如果有就直接返回出错

#048                 /* Check  an Irp is already pending */
#049                  (WaitingIrp)
#050                 {
#051                     /* Unable to have a 2nd pending IRP for this IOCTL */
#052                     WARN_(I8042PRT, "Unable to pend a second IRP for IOCTL_GET_SYS_BUTTON_EVENT\n");
#053                     Status = STATUS_INVALID_PARAMETER;
#054                     Irp->IoStatus.Status = Status;
#055                     IoCompleteRequest(Irp, IO_NO_INCREMENT);
#056                 }
#057                 
#058                 {


  如果电源IRP已经准备好就直接返回给系统

#059                     ULONG PowerKey;
#060                     PowerKey = InterlockedExchange((PLONG)&DeviceExtension->LastPowerKey, 0);
#061                      (PowerKey != 0)
#062                     {
#063                         (VOID)InterlockedCompareExchangePoer(&DeviceExtension->PowerIrp, NULL, Irp);
#064                         *(PULONG)Irp->AssociatedIrp.Buffer = PowerKey;
#065                         Status = STATUS_SUCCESS;
#066                         Irp->IoStatus.Status = Status;
#067                         Irp->IoStatus.Information = (ULONG);
#068                         IoCompleteRequest(Irp, IO_NO_INCREMENT);
#069                     }
#070                     
#071                     {
#072                         TRACE_(I8042PRT, "Pending IOCTL_GET_SYS_BUTTON_EVENT\n");
#073                         Status = STATUS_PENDING;
#074                         Irp->IoStatus.Status = Status;
#075                         IoMarkIrpPending(Irp);
#076                     }
#077                 }
#078                  Status;
#079             }
#080             ;
#081         }


  缺省是ForwardIrpAndForget把IRP前面传送

#082         default:
#083         {
#084             ERR_(I8042PRT, "IRP_MJ_DEVICE_CONTROL / unknown ioctl code 0x%lx\n",
#085                 Stack->Parameters.DeviceIoControl.IoControlCode);
#086             ASSERT(FALSE);
#087              ForwardIrpAndForget(DeviceObject, Irp);
#088         }
#089     }
#090 
#091     Irp->IoStatus.Status = Status;
#092      (Status  STATUS_PENDING)


  这里IoMarkIrpPending来标记IRP正在阻塞中

#093         IoMarkIrpPending(Irp);
#094     
#095         IoCompleteRequest(Irp, IO_NO_INCREMENT);
#096 
#097      Status;
#098  }


  下面来分析i8042InternalDeviceControl实现代码如下:

#001   NTSTATUS NTAPI
#002  i8042InternalDeviceControl(
#003     IN PDEVICE_OBJECT DeviceObject,
#004     IN PIRP Irp)
#005  {
#006     PFDO_DEVICE_EXTENSION DeviceExtension;
#007     ULONG ControlCode;
#008     NTSTATUS Status;
#009 
#010     TRACE_(I8042PRT, "i8042InternalDeviceControl(%p %p)\n", DeviceObject, Irp);


  获取设备扩展

#011     DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
#012 


  根据设备扩展类型处理

#013     switch (DeviceExtension->Type)
#014     {


  不知道类型处理

#015          Unknown:
#016         {


  获取控制码

#017             ControlCode = IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.IoControlCode;

  根据控制码来处理

#018             switch (ControlCode)
#019             {


  内部键盘连接处理

#020                  IOCTL_INTERNAL_KEYBOARD_CONNECT:

  进行内部IRP处理

#021                     Status = i8042KbdInternalDeviceControl(DeviceObject, Irp);
#022                     ;


  内部鼠标连接处理

#023                  IOCTL_INTERNAL_MOUSE_CONNECT:
#024                     Status = i8042MouInternalDeviceControl(DeviceObject, Irp);
#025                     ;
#026                 default:
#027                     ERR_(I8042PRT, "Unknown IO control code 0x%lx\n", ControlCode);
#028                     ASSERT(FALSE);
#029                     Status = STATUS_INVALID_DEVICE_REQUEST;
#030                     ;
#031             }
#032             ;
#033         }




  键盘处理内部IRP

#034          Keyboard:
#035             Status = i8042KbdInternalDeviceControl(DeviceObject, Irp);
#036             ;


  鼠标处理内部IRP

#037          Mouse:
#038             Status = i8042MouInternalDeviceControl(DeviceObject, Irp);
#039             ;
#040         default:
#041             ERR_(I8042PRT, "Unknown FDO type %u\n", DeviceExtension->Type);
#042             ASSERT(FALSE);
#043             Status = STATUS_INTERNAL_ERROR;
#044             IoCompleteRequest(Irp, IO_NO_INCREMENT);
#045             ;
#046     }
#047 
#048      Status;
#049  }




标签:reactos
0

相关文章

读者评论

发表评论

  • 昵称:
  • 内容: