⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jiurl键盘驱动 4.htm

📁 JIURL键盘驱动
💻 HTM
📖 第 1 页 / 共 5 页
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0058)http://jiurl.nease.net/cn/document/KbdDriver/JiurlKbd4.htm -->
<HTML><HEAD><TITLE>JIURL键盘驱动 4</TITLE>
<META http-equiv=Content-Type content="text/html; charset=gb2312">
<STYLE type=text/css>.title {
	FONT-WEIGHT: bold; FONT-SIZE: 21px; LINE-HEIGHT: 48px; FONT-FAMILY: "黑体", Arial, sans-serif; TEXT-DECORATION: none
}
.author {
	FONT-SIZE: 12px; LINE-HEIGHT: 16px; FONT-FAMILY: "宋体"
}
.content {
	FONT-SIZE: 14px; LINE-HEIGHT: 20px
}
</STYLE>

<META content="MSHTML 6.00.2900.2668" name=GENERATOR></HEAD>
<BODY bgColor=#f7f7f7 topMargin=5>
<DIV align=center>
<CENTER>
<TABLE height=29 cellSpacing=0 cellPadding=0 width="96%" border=0>
  <TBODY>
  <TR>
    <TD class=title width="100%" height=41>
      <P align=center><FONT face=宋体>JIURL键盘驱动 </FONT><FONT 
    face=宋体>4</FONT></P></TD></TR></CENTER>
  <TR>
    <TD class=author width="100%" height=9>
      <P align=center><FONT face=宋体>作者: <A 
      href="mailto:jiurl@mail.china.com">JIURL</A> </FONT></P></TD></TR>
  <TR>
    <TD class=author width="100%" height=6>
      <P align=center><FONT 
      face=宋体>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
      主页: <A href="http://jiurl.yeah.net/">http://jiurl.yeah.net/</A> 
    </FONT></P></TD></TR>
  <TR>
    <TD class=author width="100%" height=2>
      <P align=center><FONT face=宋体>&nbsp;&nbsp;&nbsp; 日期: 2003-12-13</FONT> 
    </P></TD></TR></TBODY></TABLE></DIV>
<DIV align=center>
<CENTER>
<TABLE height=1 cellSpacing=0 cellPadding=0 width="96%" border=0>
  <TBODY>
  <TR>
    <TD width="100%" height=1>
      <HR color=#396da5 SIZE=3>
    </TD></TR></TBODY></TABLE></CENTER></DIV>
<DIV align=center>
<TABLE class=content height=200 cellSpacing=0 cellPadding=0 width="96%" 
border=0>
  <TBODY>
  <TR>
    <TD vAlign=top width="131%" height=200>
      <P>6.2 初始化与注册表<BR><BR>在驱动的初始化中,注册表起着非常重要的作用。<BR><BR>6.2.1 
      重要认识<BR><BR>&nbsp;&nbsp;&nbsp; 
      每台计算机的硬件配置可能是不同的,系统是如何知道需要为哪些硬件载入驱动?系统是如何知道要载入的驱动文件是哪个文件?答案是通过注册表,注册表中保存着这些信息。那么注册表中的这些信息是哪里来的?答案是在安装驱动的时候,安装程序放到注册表中的。<BR><BR>6.2.2 
      确定驱动载入顺序的基本知识<BR><BR>&nbsp;&nbsp;&nbsp; 
      在系统初始化的时候,决定驱动程序在什么时候被载入的信息保存在注册表中。最早的一批驱动是由ntldr载入内存的(仅仅是载入),第二批是由IO管理器载入内存的,第三批是由 
      SCM(Service Control Manager) 载入的。一个驱动在第几批中被载入是由 
      HKLM\SYSTEM\CurrentControlSet\Services\驱动名\Start 
      的值来决定。该值为0,第一批被载入。该值为1,第二批被载入。该值为2,第三批被载入。对于同一批驱动中的驱动,按驱动所在组的先后载入。组的先后顺序由 
      HKLM\SYSTEM\CurrentControlSet\Control\ServiceGroupOrder\List 决定。每个驱动的 
      HKLM\SYSTEM\CurrentControlSet\Services\驱动名\Group 决定了驱动所属的组,如果没有这个 
      Services\驱动名\Group ,那么就在所有组之后。对于同一个组中的驱动,按驱动的Tag的先后载入。Tag的先后顺序由 
      HKLM\SYSTEM\CurrentControlSet\Control\GroupOrderList\组名 决定。每个驱动的 
      HKLM\SYSTEM\CurrentControlSet\Services\驱动名\Tag 
      决定了驱动在组中的Tag。<BR><BR>&nbsp;&nbsp;&nbsp; 
      关于系统初始化过程和如何确定驱动载入的顺序的更详细内容,可以参考下面两个资料:<BR>Inside the Boot Process Part 1 
      ,Inside the Boot Process Part 2 
      。<BR>http://osg.informatik.tu-chemnitz.de/lehre/seminar/lwb/Doku/SystemInitiation.pdf 
      。<BR>"6.2.2 确定驱动载入顺序的基本知识"的内容就是从这两个资料中翻译的。<BR><BR>6.2.3 
      注册表与设备栈<BR><BR>&nbsp;&nbsp;&nbsp; 
      设备栈的建立,是靠注册表中的信息。这些信息放在以下两个键下。<BR>HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\<BR>HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\&nbsp;<BR>具体请看,稍后对注册表中决定键盘设备栈的信息的讨论。<BR><BR>参考 
      ...\NTDDK\src\general\toaster\toaster.htm<BR><BR>6.2.4 
      驱动文件的路径<BR><BR>HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\驱动名\ImagePath<BR><BR>6.2.5 
      键盘驱动与注册表<BR><BR>6.2.5.1 键盘驱动载入顺序<BR><BR>查看注册表中决定键盘驱动 i8042prt, kbdclass 
      载入顺序的内容。<BR><BR>[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\i8042prt]<BR>"Type"=dword:00000001<BR>"Start"=dword:00000001<BR>"Group"="Keyboard 
      Port"<BR>"ErrorControl"=dword:00000001<BR>"DisplayName"="i8042 Keyboard 
      and PS/2 Mouse Port 
      Driver"<BR>"ImagePath"="System32\DRIVERS\i8042prt.sys"<BR>"Tag"=dword:00000004<BR><BR>[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Kbdclass]<BR>"ErrorControl"=dword:00000001<BR>"Group"="Keyboard 
      Class"<BR>"Start"=dword:00000001<BR>"Tag"=dword:00000001<BR>"Type"=dword:00000001<BR>"DisplayName"="Keyboard 
      Class Driver"<BR>"ImagePath"="System32\DRIVERS\kbdclass.sys"<BR><BR>两个的 
      Start 类型都是 1,即 SERVICE_SYSTEM_START ,所以他们都将由 IO 管理器载入。还可以看到 i8042prt 属于组 
      "Keyboard Port" ,kbdclass 属于组 "Keyboard Class" 
      。<BR><BR>查看这两个组的先后顺序。组的先后顺序保存在 
      HKEY_LOCAL_MACHINE\CurrentControlSet\Control\ServiceGroupOrder\List 中,由于使用 
      regedit.exe 来看这个值不是很方便,我们使用系统中另一个注册表编辑器regedt32.exe 。 
      可以看到下面的内容。<BR><BR>System Reserved<BR>...<BR>Keyboard Port<BR>Pointer 
      Class<BR>Keyboard Class<BR>...<BR>MS Transactions<BR><BR>组 "Keyboard Port" 
      在 组 "Keyboard Class" 之前,所以 i8042prt 在 kbdclass 
      之前被载入。<BR><BR>确定了顺序之后,HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\驱动名\ImagePath 
      是驱动程序文件的路径,通过这个值,就可以在硬盘上找到驱动程序文件,也就可以把它读入内存。<BR><BR>6.2.5.2 
      键盘设备栈与注册表<BR><BR>[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0303\4&amp;5289e18&amp;0]<BR>"Capabilities"=dword:00000020<BR>"HardwareID"=hex(7):41,00,43,00,50,00,49,00,5c,00,50,00,4e,00,50,00,30,00,33,\<BR>00,30,00,33,00,00,00,2a,00,50,00,4e,00,50,00,30,00,33,00,30,00,33,00,00,00,\<BR>00,00<BR>"Service"="i8042prt"<BR>"ClassGUID"="{4D36E96B-E325-11CE-BFC1-08002BE10318}"<BR>"ConfigFlags"=dword:00000000<BR>"Driver"="{4D36E96B-E325-11CE-BFC1-08002BE10318}\\0000"<BR>"Mfg"="(标准键盘)"<BR>"DeviceDesc"="Standard 
      101/102-Key or Microsoft Natural PS/2 
      Keyboard"<BR><BR>[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4D36E96B-E325-11CE-BFC1-08002BE10318}]<BR>"Class"="Keyboard"<BR>"Icon"="-3"<BR>"Installer32"="SysSetup.Dll,KeyboardClassInstaller"<BR>"UpperFilters"="kbdclass"<BR>@="键盘"<BR>"NoInstallClass"="1"<BR>"TroubleShooter-0"="tshoot.chm,hdw_keyboard.htm"<BR><BR>HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0303\4&amp;5289e18&amp;0\Service<BR>通过这里找到键盘设备栈中的 
      i8042prt<BR><BR>HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ACPI\PNP0303\4&amp;5289e18&amp;0\ClassGUID<BR>通过这里找到类的GUID,用这个GUID就可以在 
      HKLM\SYSTEM\CurrentControlSet\Control\Class\ 
      下找到键盘驱动类,进而找到键盘类的过滤程序<BR><BR>HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4D36E96B-E325-11CE-BFC1-08002BE10318}\UpperFilters<BR>通过这里找到键盘设备栈中的 
      kbdclass<BR><BR><BR>6.3 键盘驱动初始化分析<BR><BR>6.3.1 
      键盘驱动本身的初始化部分<BR><BR>系统初始化进行到下图所示阶段 
      <P align=center><IMG src="JIURL键盘驱动 4.files/init1.gif" border=0> 
      <P>[i8042prt!DriverEntry]<BR><BR>此时的 Call Stack<BR><BR># ChildEBP RetAddr 
      Args to Child&nbsp;<BR>00 f901f510 804a4431 fe4f69f0 fe4f5000 00000000 
      i8042prt!DriverEntry(struct _DRIVER_OBJECT * DriverObject = 0xfe4f69f0, 
      struct _UNICODE_STRING * RegistryPath = 0xfe4f5000) (CONV: stdcall)<BR>01 
      f901f5d8 80426f6d 80000044 fe4f5000 f901f6e0 nt!IopLoadDriver+0x672 (FPO: 
      [Non-Fpo])<BR>02 f901f608 8049ccaa fe4f7348 80000044 00000001 
      nt!IopCallDriverAddDeviceQueryRoutine+0x356 (FPO: [Non-Fpo])<BR>03 
      f901f654 80497df1 00000012 00000001 f901f6b0 
      nt!RtlpCallQueryRegistryRoutine+0x349 (FPO: [Non-Fpo])<BR>04 f901f6b8 
      804a4ac0 00000000 00000082 00000001 nt!RtlQueryRegistryValues+0x1ed (FPO: 
      [Non-Fpo])<BR>05 f901f77c 8054f1bb 80000048 00000001 f901f864 
      nt!IopCallDriverAddDevice+0x38f (FPO: [Non-Fpo])<BR>06 f901f798 804e504e 
      fe4fed68 f901f864 fe4d6368 nt!IopProcessAddDevicesWorker+0x6c (FPO: 
      [2,0,3])<BR>07 f901f7a8 8054f184 fe4d6368 8054f147 f901f864 
      nt!IopForAllChildDeviceNodes+0x1f (FPO: [3,0,1])<BR>08 f901f7c4 804e504e 
      fe4d6368 f901f864 fe4e7c28 nt!IopProcessAddDevicesWorker+0x3d (FPO: 
      [2,0,3])<BR>09 f901f7d4 8054f184 fe4e7c28 8054f147 f901f864 
      nt!IopForAllChildDeviceNodes+0x1f (FPO: [3,0,1])<BR>0a f901f7f0 804e504e 
      fe4e7c28 f901f864 fe5181a8 nt!IopProcessAddDevicesWorker+0x3d (FPO: 
      [2,0,3])<BR>0b f901f800 8054f184 fe5181a8 8054f147 f901f864 
      nt!IopForAllChildDeviceNodes+0x1f (FPO: [3,0,1])<BR>0c f901f81c 804e504e 
      fe5181a8 f901f864 fe51b5e8 nt!IopProcessAddDevicesWorker+0x3d (FPO: 
      [2,0,3])<BR>0d f901f82c 8054f184 fe51b5e8 8054f147 f901f864 
      nt!IopForAllChildDeviceNodes+0x1f (FPO: [3,0,1])<BR>0e f901f848 8054f114 
      fe51b5e8 f901f864 00000003 nt!IopProcessAddDevicesWorker+0x3d (FPO: 
      [2,0,3])<BR>0f f901f86c 8054dfdf fe51baa8 0000ffff 00000003 
      nt!IopProcessAddDevices+0x59 (FPO: [Non-Fpo])<BR>10 f901f8c0 8054c5c9 
      00000000 00000032 00000000 nt!IopInitializeSystemDrivers+0x25 (FPO: 
      [Non-Fpo])<BR>11 f901fa58 8054b35a 80087000 00000000 00000000 
      nt!IoInitSystem+0x644 (FPO: [Non-Fpo])<BR>12 f901fda8 804524f6 80087000 
      00000000 00000000 nt!Phase1Initialization+0x71b (FPO: [Non-Fpo])<BR>13 
      f901fddc 80465b62 8054aca6 80087000 00000000 
      nt!PspSystemThreadStartup+0x69 (FPO: [Non-Fpo])<BR><BR>可以看到是 IO 管理器调用 
      nt!IopLoadDriver 载入了驱动文件 i8042prt.sys,并调用 
      i8042prt!DriverEntry。<BR><BR>介绍一下 nt!IopLoadDriver 
      的执行过程<BR><BR>nt!IopLoadDriver 会遍历 PsLoadedModuleList ,查看是否已经有叫 
      i8042prt.SYS 的模组。也就是查看是否 i8042prt.SYS 已经被载入。发现没有载入,就读取 "ImagePath" 
      下的数据,获得了路径 "System32\DRIVERS\i8042prt.sys"。使用获得的路径做参数,调用 
      nt!MmLoadSystemImage,载入驱动。使用 nt!ObCreateObject 
      创建一个驱动对象。按下面的叙述顺序初始化这个驱动对象。给 DRIVER_OBJECT 的 +18 struct _DRIVER_EXTENSION 
      *DriverExtension 赋值,驱动对象的首地址加上0xa8,即紧跟在 DRIVER_OBJECT 之后的地址。将 
      DRIVER_EXTENSION 的 +00 struct _DRIVER_OBJECT *DriverObject 赋值为驱动对象的首地址。用 
      nt!IopInvalidDeviceRequest 初始化驱动对象的整个 MajorFunction[28] 。初始化驱动对象的 
      Type,Size,Flags。用 i8042prt!DriverEntry 初始化驱动对象的 +2c function *DriverInit 
      。初始化 +14 void *DriverSection 。用 i8042prt 在内存中的首地址初始化 +0c void *DriverStart 
      。用 i8042prt 的大小初始化 +10 uint32 DriverSize 。用 nt!ObInsertObject 将 
      DRIVER_OBJECT 插入命名对象空间,即在插入前 \driver\ 下是没有 i8042prt 的,插入后就有了。初始化 +24 
      struct _UNICODE_STRING *HardwareDatabase 。从 PagedPool 分配内存,用刚分配的内存初始化 +1c 
      struct _UNICODE_STRING DriverName,放入 "\Driver\i8042prt"。从 NonPagedPool 
      分配内存,初始化 DRIVER_EXTENSION 的 ServiceKeyName,放入 "i8042prt"。将 PUNICODE_STRING 
      RegistryPath ,PDRIVER_OBJECT DriverObject 压入堆栈,然后调用 DriverObject+0x2c 即 
      DriverInit 即 DriverEntry。从 DriverEntry 中返回之后,nt!IopLoadDriver 继续执行,会释放为 
      RegistryPath 所申请的空间。<BR><BR>DriverEntry(<BR>IN PDRIVER_OBJECT 
      DriverObject,<BR>IN PUNICODE_STRING RegistryPath<BR>)<BR><BR>RegistryPath 
      指向的 unicode 字符串为 
      "\REGISTRY\MACHINE\SYSTEM\ControlSet001\Services\i8042prt"<BR>此时我的 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -