您的位置:首页 > Web前端 > React

reactos操作系统实现(94)

2009-09-23 22:57 369 查看
现在就来依次分析函数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 return 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 return 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 return STATUS_SUCCESS;
#012 }

函数i8042DeviceControl,它的实现代码如下:
#001 static 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 case Keyboard:
#015 return i8042KbdDeviceControl(DeviceObject, Irp);
#016 break;
#017 default:
#018 return IrpStub(DeviceObject, Irp);
#019 }
#020
#021 return 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 case IOCTL_GET_SYS_BUTTON_CAPS:
#017 {
#018 /* Part of GUID_DEVICE_SYS_BUTTON interface */
#019 PULONG pCaps;
#020 TRACE_(I8042PRT, "IOCTL_GET_SYS_BUTTON_CAPS/n");
#021

如果返回参数内存空间不够4个字节长,就返回非法参数。
#022 if
(Stack->Parameters.DeviceIoControl.OutputBufferLength != sizeof(ULONG))
#023 Status = STATUS_INVALID_PARAMETER;
#024 else
#025 {

获取系统保存参数位置。
#026 pCaps = (PULONG)Irp->AssociatedIrp.SystemBuffer;

把键盘的大写状态返回给系统。
#027 *pCaps = DeviceExtension->NewCaps;
#028 DeviceExtension->ReportedCaps =
DeviceExtension->NewCaps;

设置IRP返回参数的长度为4个字节。
#029 Irp->IoStatus.Information = sizeof(ULONG);

设置返回状态为成功。
#030 Status = STATUS_SUCCESS;
#031 }
#032 break;
#033 }

获取系统按键事件。
#034 case IOCTL_GET_SYS_BUTTON_EVENT:
#035 {
#036 /* Part of GUID_DEVICE_SYS_BUTTON interface */
#037 PIRP WaitingIrp;
#038 TRACE_(I8042PRT,
"IOCTL_GET_SYS_BUTTON_EVENT/n");
#039

判断是否可以返回参数,如果不可以返回,就直接返回出错。
#040 if
(Stack->Parameters.DeviceIoControl.OutputBufferLength != sizeof(ULONG))
#041 Status = STATUS_INVALID_PARAMETER;
#042 else
#043 {

获取电源按键的事件。
#044 WaitingIrp = InterlockedCompareExchangePointer(
#045 &DeviceExtension->PowerIrp,
#046 Irp,
#047 NULL);

已经有一个事件的IRP在等待中,如果有就直接返回出错。
#048 /* Check if an Irp is already pending */
#049 if (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 else
#058 {

如果电源的IRP已经准备好,就直接返回给系统。
#059 ULONG PowerKey;
#060 PowerKey =
InterlockedExchange((PLONG)&DeviceExtension->LastPowerKey, 0);
#061 if (PowerKey != 0)
#062 {
#063 (VOID)InterlockedCompareExchangePointer(&DeviceExtension->PowerIrp,
NULL, Irp);
#064 *(PULONG)Irp->AssociatedIrp.SystemBuffer =
PowerKey;
#065 Status = STATUS_SUCCESS;
#066 Irp->IoStatus.Status = Status;
#067 Irp->IoStatus.Information = sizeof(ULONG);
#068 IoCompleteRequest(Irp, IO_NO_INCREMENT);
#069 }
#070 else
#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 return Status;
#079 }
#080 break;
#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 return ForwardIrpAndForget(DeviceObject, Irp);
#088 }
#089 }
#090
#091 Irp->IoStatus.Status = Status;
#092 if (Status == STATUS_PENDING)

这里调用函数IoMarkIrpPending来标记IRP正在阻塞中。
#093 IoMarkIrpPending(Irp);
#094 else
#095 IoCompleteRequest(Irp, IO_NO_INCREMENT);
#096
#097 return Status;
#098 }

下面来分析函数i8042InternalDeviceControl的实现,代码如下:
#001 static 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 case Unknown:
#016 {

获取控制码。
#017 ControlCode =
IoGetCurrentIrpStackLocation(Irp)->Parameters.DeviceIoControl.IoControlCode;

根据控制码来处理。
#018 switch (ControlCode)
#019 {

内部键盘连接处理。
#020 case IOCTL_INTERNAL_KEYBOARD_CONNECT:

进行内部的IRP处理。
#021 Status =
i8042KbdInternalDeviceControl(DeviceObject, Irp);
#022 break;

内部鼠标连接处理。
#023 case IOCTL_INTERNAL_MOUSE_CONNECT:
#024 Status =
i8042MouInternalDeviceControl(DeviceObject, Irp);
#025 break;
#026 default:
#027 ERR_(I8042PRT, "Unknown IO control code
0x%lx/n", ControlCode);
#028 ASSERT(FALSE);
#029 Status = STATUS_INVALID_DEVICE_REQUEST;
#030 break;
#031 }
#032 break;
#033 }

键盘处理内部IRP。
#034 case Keyboard:
#035 Status = i8042KbdInternalDeviceControl(DeviceObject, Irp);
#036 break;

鼠标处理内部IRP。
#037 case Mouse:
#038 Status = i8042MouInternalDeviceControl(DeviceObject, Irp);
#039 break;
#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 break;
#046 }
#047
#048 return Status;
#049 }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: