reactos操作系统实现(94)
现在就来依次分析函数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,"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,"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",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} (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |