??xml version="1.0" encoding="utf-8" standalone="yes"?>久久99精品国产麻豆婷婷,久久久久99精品成人片欧美,久久露脸国产精品 http://www.shnenglu.com/Walker/articles/147058.html漫步者?amp;…?K?/dc:creator>漫步者?amp;…?K?/author>Tue, 24 May 2011 13:41:00 GMT http://www.shnenglu.com/Walker/articles/147058.html http://www.shnenglu.com/Walker/comments/147058.html http://www.shnenglu.com/Walker/articles/147058.html#Feedback 0 http://www.shnenglu.com/Walker/comments/commentRss/147058.html http://www.shnenglu.com/Walker/services/trackbacks/147058.html 2 加锁与解锁不匚w ]]> .INF文g http://www.shnenglu.com/Walker/articles/146850.html漫步者?amp;…?K?/dc:creator>漫步者?amp;…?K?/author>Sat, 21 May 2011 01:21:00 GMT http://www.shnenglu.com/Walker/articles/146850.html http://www.shnenglu.com/Walker/comments/146850.html http://www.shnenglu.com/Walker/articles/146850.html#Feedback 0 http://www.shnenglu.com/Walker/comments/commentRss/146850.html http://www.shnenglu.com/Walker/services/trackbacks/146850.html 1?INF文g是什?br /> .INF?Device Information File 的羃写,是微软公ؓ(f)供硬件设备制造商发布其设备驱动程序而发展的——许多g讑֤的驱动程序都是?.INF文g来安装的?INF文g?Windows3.X 时代开始大量被使用?jin)?br /> .INF 文g是一U具有特定格式的U文本文Ӟ我们可说它是一U安装脚本(SetupScriptQ。虽?.INF 只是U文本文Ӟ但是当我们在文g理器explorer?.INF文g按鼠标右键後Q在右键菜单上就?x)出?#8220;安装”命o(h)Q这是因为微软公司已在其操作pȝ Windows 中内|提供了(jin) Setup APIQ可以解?INF脚本文gQ,我们只需用文本编辑Y件编?.INF文gQ便可完成大部䆾的安装工作,所以尤其是在Y体的大小q不是很大的情况下,安装工作不是很复杂的时候,使用 .INF文g来进行安装工作将?x)是一个好选择。而且如果要安装设备驱动程序,.INF文g是目前唯一的选择?可以?.INF文g创徏包括注册表条目和目的目录的自定义软g安装指o(h)?INF文g可以提供有限的^台独立性,q指定有限的软g依赖性。目?INF文g最?遍的应用是ؓ(f)安装g讑֤的驱动程序服务的Q本文的目的是介绍 .INF文g的功能、结构、ƈ提供?jin)几个事例来说明如何?INF文gQ如何扩?INF文g的用途,比如制作l色软gQ仅供参考?br />2?INF文g的格?/strong> .INF文g是由许多节(SectionQ组成,?INI文gcMQ整?INF文g由几个节l成Q节名用?括号扩v来,如version 节,Manufacturer节,和Strings节等{。而每个节又由一pd的条目组成,每个条目都是是由一个键QKeyQ与一个|ValueQ组 成,都是“Key=Value”q样的Ş式,在这些节中定义的目可以完成g的自动检和软gQ包括驱动程序)(j)的安装?INF文g中分号后面的字符?是注释。在一?.INF文g中,所有跟随在分号Q?Q后的文字都?x)被视?f)注释。注释ƈ不一定要在新行开始,可以在一行文字後面加入注释?br />3?INF文g案格式和作用如下所C:(x) [Version] 节:(x) 包含Ҏ(gu) .INF文g的简短描qC?.INF文g支持的设备类型的信息。用于确?.INF文g的基本版本信息。Q?INF文g都必?包括q个节?[Version] 节中的语?Signature="$CHICAGO$"表明q个.INF文g可以用于windows 95以后的所有^CQ目前来说就是win98QwinmeQwinnt4Qwin2kQwinxpQwin2k3。这U?INF文g比较多见?nbsp; 如果 [Version]节中的签名条目是 Signature="$Windows 95$"Q表明这?INF文g可以用于windows 95以后的Win9xq_上,目前来说是win98Qwinme? 如果[Version]节中的签名条目是 Signature="$WINDOWS NT$"Q表明这?INF文g可以用于WindowsNTpd的^CQ包括winnt4Qwin2kQwinxpQwin2k3。WIN9xpd的操 作系l的SetupAPI会(x)拒绝执行q种cd?INF文g?br /> [Manufacturer] ?[Manufacturer Name] 节:(x) 列出?.INF文g可L识的所有硬件设备,q列Z(jin)开发该g的厂商名Uͼ主要用于g讑֤的安装。在讑֤驱动E序?INF文g中必d?[Manufacturer]节与 [Manufacturer Name] 节。[Manufacturer]节和[Microsoft]节,安装新硬件的向导中列出来的厂商名字和讑֤?U就是来自这两个节。这行语?#8220;%MfgName%=Microsoft” 的等号右边的名字指明讑֤刉商是MicrosoftQ等号左Ҏ(gu)厂商的名字,厂商名称?Microsoft"Q在后面讲到的[Strings] 节中Q。在一?INF文g中可以有多个讑֤刉商的名字,都必L在[Manufacturer]节中Q同时[Manufacturer Name] 节可以列?gu)厂商的多U设备? [Manufacturer Name] 节区含有对要安装的设备的描述Qƈ安装的设备指?[Install] 节区?br /> [Manufacturer Name]节语法:(x) [manufacturer-name] device-description=install-section-name,device-id[,compatible-device-id]... device -description是对要安装的设备的描述。install-section-name是此设备的 [Install] 节区名称Qmanufacturer-name 节区名称必须已在 [Manufacturer] 节区中被定义。device-id是此讑֤的硬件标志符Q每个厂家的不同的硬件对应着不同的设备标志符?br /> 普通的安装软g?INF文g中,不包括[Manufacturer] ?[Manufacturer Name] 节,即包含Q也不会(x)执行它们Q这2个节仅仅用于g的设备驱动中起作用?br /> [Install] 节:(x) 描述讑֤驱动E序与硬件设备的实际属性。它也定义了(jin)所?[Install] 节的名称Q在此定义的节中包含?jin)安装该讑֤的信息和命o(h)。默认情况下Q会(x)执行 [DefaultInstall] 节,Install操作׃(x)执行[DefaultInstall] 节。[DefaultInstall] 节中包含指向其他节的指针Q该节可用于指定要复制和删除的文件、注册表的更新?INF文g的更新等?br /> 如果是安装普通的软g?INF文gQ可以通过鼠标右键菜单上的“安装”命o(h)来安装,q个时?INF文g必须包括 [DefaultInstall]节,也可以包括其他的[Install]节,用RUNDLL32.EXE ETUPAPI.DLL,InstallHinfSection [Install]节的名字Q这L(fng)似的命o(h)来安装?br /> [Install]节的语法Q?br />[install-section-name] Copyfiles=file-list-section[,file-list-section]... LogConfig=log-config-section-name Renfiles=file-list-section[,file-list-section]... Delfiles=file-list-section[,file-list-section]... UpdateInis=update-ini-section[,update-ini-section]... UpdateIniFields=update-inifields-section[,update-inifields-section]... AddReg=add-registry-section[,add-registry-section]... DelReg=del-registry-section[,del-registry-section]... Ini2Reg=ini-to-registry-section[,ini-to-registry-section]... UpdateCfgSys=update-config-section UpdateAutoBat=update-autoexec-section [Install] 节定义了(jin)安装E式与硬体驱动需要的资源Q以便安装新的驱动程式或者Y件?br />此节中每个条目都有其特定格式与意义,q每个条目都是必要的。无论是安装驱动E序q是普通的软gQ最后都要从某一个[Install] 节开始执行? [DestinationDirs] 节:(x) 指定盘?sh)复制、删除或重命名节文g的位|(例如 \Windows ?Windows\SystemQ?.INF文g通过[DestinationDirs]节来指定操作的目标\径,语法如下Q?br />[DestinationDirs] file-list-section =ldid[, subdir ] DefaultDestDir=ldid[, subdir ] [DestinationDirs] 节定义了(jin) [file-list-section] 节中指定的操作(可以?CopyFiles、RenFiles ?DelFiles 节)(j)的目标目录。DefaultDestDir命o(h)可以?.INF文g中的M没有明确在[DestinationDirs]节中命名的CopyFiles、RenFiles或DelFiles节指定默认目标文 件夹?br /> [FileCopy/Delete/RenameSection(s)] 节:(x)列出要复制、删除或重命名的文g?节的名字是CopyFilesQDelFilesQRenFiles?br />[RegistryUpdateSection(s)] 节:(x)指定在注册表中添加或删除的项目?节的名字是AddRegQDelReg?br />[IniFileUpdateSection(s)] 节:(x)指定 .ini 文g的更新。链接将在该节中创徏?节的名字?UpdateInis?br /> ?INF文g中,使用逻辑盘标识W?(LDID) 来表C\径,如下表:(x) 00 Null LDID - 可用于创建新?LDID 01 Source Drive:\pathname 10 Windows 文g夹({h(hun)?windir%目录 Q? 11 System 文g? 12 IOSubsys 文g? 13 Command 文g? 17 Inf 文g? 18 Help 文g? 20 Fonts 21 Viewers 22 VMM32 23 Color 文g? 24 包含 Windows 文g夹的驱动器根目录 28 Host Winboot 30 启动盘的Ҏ(gu)件夹 31 虚拟启动盘的主驱动器Ҏ(gu)件夹 [ClassInstall] 节:(x)备定义一个新的类别(ClassQ。主要用于硬件设备的安装?br />[SourceDisksNames] 节:(x) 列出包含文g的磁盘? [SourceDisksFiles] 节:(x) 列出每个文g所在的特定盘? 其他的节q有许多Q如QUpdate .ini Fields ?(UpdateIniFields)QAdd Ini File to Registry ?(Ini2Reg)QUpdate Config.sys ?(UpdateCfgSys)QUpdate Autoexec.bat ?(UpdateAutoBat)QOptional Components 节,{等? .INF文g 是由Windows的SetupAPI解释执行的脚本文Ӟ它的q行q程很简单,是一U线性的执行Q线性的意思就?INF文g的运行过E不存在分支?句,也就是没有条件语句,一旦开始执行,是沿着固定的\U运行。它的运行是按照节ؓ(f)单位来执行的Q从某一个[Install]节开始执行,从上C执行 该节中的条目Q如果该条目是一个节Q那么就一条条执行子节中的条目Q如此递归执行?br /> q样的脚本看h功能很弱Q但是对于简单的安装d已经_ ?jin),安装不外乎复制文Ӟd注册表,修改.INI文g{Q务,q些都可以用.INF文g来完成。对于更复杂的安装要求,如要求安装程序的界面漂亮方便Q?要求有选择性的安装Q要求安装程序自动修复的功能Q就只好求助于其他的工具?jin),如微软的Windows InstallerQ就具备更加强大的功能?br />4?INF文g的版?/strong> .INF文g的语法是l一的分节语法,随着操作pȝ的更斎ͼ微Y逐渐增加?jin)一些必要的关键字,但是整个?INF文g的结构不?x)变化。从语法上来_(d).INF文g都是一个类别?br />按照.INF文g的版本来分类Q可以分?c:(x) 1 AdvancedINFQ在[Version]节中?#8220;AdvancedINF=2.5,"(zhn)需要新版本?AdvPack.dll" ”q么一行语句,表明?INF文g需要AdvPack.dllq个动态链接库来解释执行,AdvancedINF有一些高U特性,但是在目前用的不?多?br />2 普通INFQ没有指明需要AdvPack.dll?INF文gQ用SetupAPI.DLL来解释执行(win9xpd的操作系l用Setupx.dllQ,pȝ中缺省用的是q种普通INF?br />5?INF文g的功?/strong> 从前面的介绍Q能够看Z?.INF文g可以完成如下功能Q?br />1 复制文g、删除文件、或重新命名文g?br />2 新增或删除注册表QRegistryQ中的项目?br />3 修改重要的系l设|文Ӟ?Autoexec.bat、Config.sys?INI {)(j)?br />_?看v来,g上面提到的第一个功能可以用批处理文?BAT来完成,W二个功能可以通过注册表文?REG来完成,W三个功能现在用得不多,不经常处? INI文g?jin)。这栯hg.INF文g也没有太大的优势啊。这U看法是有问题的Q下面我会(x)着重指?INF在在q几个方面的应用Q而不?x)仔l讲? INF的语法?下面要提?INF文g优(sh)别的工具的方面?6、用.INF文g~辑注册?/strong> .INF文g可以~辑操纵注册表,相应的的命o(h)是AddReg和DelRegQ?br />语法如下Q?br />AddReg = add-registry-section[,add-registry-section]... [ add-registry-section] reg-root-string, [subkey], [value-name], [flag], [value] [add-registry-section]节定义了(jin)要d的注册表子键或值名Q可以有选择地设|它的倹{?br />DelReg = del-registry-section[,del-registry-section]... [ del-registry-section] reg-root-string, subkey, [value-name] [ del-registry-section]节定义了(jin)要从注册表中删除子键subkey或值名value-name?br />有时候上|遇到某些网站,修改?jin)IE的主,然后用?jin)REGEDIT工具Q这个时候很多h只好借助于其他第三方工具如超U兔子等来恢复注册表的编辑权限,其实q个时候仅仅依?INF文g可以恢复用REGEDIT工具的权限? 把下面的q段代码复制到记事本里,另存?sh)jiereg.inf,然后叛_它选择“安装”Q就可以?jin)?br />[Version] Signature= "$CHICAGO$" [DefaultInstall] AddReg=My.Add.Reg [My.Add.Reg] HKCU, "SOFTWARE\Microsoft\windows\currentversion\policies\system","disableregistrytools", 0x00010001,"0" HKLM,"SOFTWARE\Microsoft\windows\currentversion\policies\system","disableregistrytools", 0x00010001,"0" 当然q可以用其他的方法,原理也是一L(fng)Q这里仅仅是演示一?INF文g的用途?br /> 直接使用注册表文Ӟ有时候还?sh)(x)遇到另外一个缺点,是.REG文g里面使用16q制代码表示UNICODE字符串的Q如下面的两条注册表语句Q?br />[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders] "Cookies"=hex(2):25,00,55,00,53,00,45,00,52,00,50,00,52,00,4f,00,46,00,49,00,4c,00,45,00,25,00, 5c,00,43,00,6f,00,6f,00,6b,00,69,00,65,00,73,00,00,00,00,00 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SoftEther] "ImagePath"=hex(2):22,00,44,00,3a,00,5c,00,50,00,72,00,6f,00,67,00,72,00,61,00,6d,00,20, 00,46,00,69,00,6c,00,65,00,73,00,5c,00,53,00,6f,00,66,00,74,00,45,00,74,00,68,00,65,00, 72,00,5c,00,53,00,6f,00,66,00,74,00,45,00,74,00,68,00,65,00,72,00,2e,00,65,00,78,00,65, 00,22,00,20,00,73,00,65,00,72,00,76,00,69,00,63,00,65,00,00,00,00,00 q上面两条语句难以阅d修改Q手工修改的话很ȝ(ch)Q其?br />"Cookies"的值实际上是“%USERPROFILE%\Cookies”字符串的UNICODE表示?br />"ImagePath"的值实际上是"D:\Program Files\SoftEther\SoftEther.exe" service 如果?INF文g的Ş式的话,很单明白了(jin): [Version] Signature="$CHICAGO$" [DefaultInstall] AddReg=Folders_AddReg [Folders_AddReg] HKCU,"Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders","Cookies",0x00020000,"%USERPROFILE%\Cookies" HKLM,"SYSTEM\CurrentControlSet\Services\SoftEther","ImagePath",0x020000,"""D:\Program Files\SoftEther\SoftEther.exe"" service" q个时候可以手工修攚w面的路径信息Q?REG文g则很隑ց到这一炏V?br />7、用.INF文g~辑.INI文g .INF文g可以使用UpdateInis命o(h)修改.INI文g的功能也l常需要,UpdateInis的语法如下:(x) UpdateInis = update-ini-section[,update-ini-section]... [ update-ini-section-name] ini-file, ini-section, [old-ini-entry], [new-ini-entry], [flags] [update-ini-section-name]节给出的 .INF 文g中替换、删除或d的全部条目。ini-file 包含要更Ҏ(gu)目的 .ini 文g名?ini-section 包含要更Ҏ(gu)目的节名?old-ini-entry 可选,常用形式?Key=Value。new-ini-entry 可选,常用形式?Key=Value。flags 是可选操作标记?br />使用逻辑盘标识W?(LDID)Q可以方便的修改.INI文g中的路径信息Q当然其他的条目也同栗D例如下:(x) Total Commander Q是一套极佳的文g理员,内含各种压羃与解压羃Q类似NC般非常好用的工具Q对于文件与路径的寻找,除一般的复制、删除、搬UR编辑等功能外,q有 FTP功能(hl传、背景传?与解决了(jin)中文q问题Q?专题"再也不会(x)变成"彩题"、新增文件分剌Ӏ文件合q、文件编码、文件解?MIMEQ?UUEQXXE)?qing)新的操作介?动工具?。真是一套相当强(zhn)可完全取代文gȝ的工L(fng)序。Total Commander依靠wincmd.ini来配|相应的操作Ҏ(gu)和功能Q于是可以用如下的.INF文g修改wincmd.ini中的路径信息Q?br />[version] Signature="$CHICAGO$" [DefaultInstall] AddReg=AddGhister UpdateInis=UpdateInicmd [AddGhister] HKCU,"Software\Ghisler\Total Commander","IniFileName",0,".\\wincmd.ini" HKCU,"Software\Ghisler\Total Commander","FtpIniName",0,".\\wcx_ftp.ini" [UpdateInicmd] %01%\wincmd.ini, Configuration,,"InstallDir=%01%" %01%\wincmd.ini, Configuration,,"Mainmenu=%01%\LANGUAGE\TCExtMenu.mnu" ??[AddGhister]节负责修Ҏ(gu)册表中记录的wincmd.ini的\径,而[UpdateInicmd]节负责修改wincmd.ini文gU的 相应路径信息Q可以看出,一个简单的.INF文g完成了(jin)修改Total Commander的\径的dQ在Total Commander5.x版本中,必须修改wincmd.ini文g中的路径信息Q这个时候?INF文g是非常方便的?br />8、用.INF文g删除正在使用的文?/strong> 有时候由于某些文件正被操作系l用而无法删除,如某些用于资源管理器的OCX控gQ可以?INF文g的DelFiles命o(h)删除Q该命o(h)如果发现要删除的文g被锁定,׃(x)把文件放到系l删除队列中排队Q等pȝ重启动的时候,该文件就自动被删除了(jin)?br />Delfiles的语法是Q?br />Delfiles= file-list-section [,file-list-section]... [file-list-section] filename,,,1 [file -list-section]节定义了(jin)要删除的文件列?filename后面?是一个标志,指明如果文g当前无法删除Q就{到pȝ重启动后删除。把 下面的这D代码复制到C本里Q另存(sh)ؓ(f)delinuse.inf,把这个文件拷贝到无法删除的文件的目录Q然后右d选择“安装(I)”Q就可以删除当前 目录下正在用的setup.exe和setup2.exe?br />[Version] Signature="$Chicago$" [DestinationDirs] DefaultDestDir = 01 ; 当前目录 Q定义了(jin)要删除的文件的路径 [DefaultInstall] DelFiles = DeleteLIST [DeleteLIST] setup.exe ,,,1; 要删除的文?br />setup2.exe ,,,1; 要删除的文?br />同样可以使用Copyfiles命o(h)替换pȝ正在讉K的文件。这些功能通过普通的del和copy命o(h)都无法实玎ͼ如果不?INF文gQ必M用第三方的Y件来完成?br />9、辅助制作绿色Y?/strong> 在注册表.REG文g中,不可以用变量,q个~陷对于需要设|\径的安装E序来说Q是非常致命的弱点,.REG文g中的路径都是?rn)态的Q一旦写好,׃?随着pȝ的变化而变化,如果需要把安装的程序从C盘改变到D盘,而在.REG文g中记录了(jin)安装路径的话Q这个时候直接倒入注册表文?REG是不行的Q导 入的注册表仍然是原来写入的\径。而在.INF文g中,可以使用变量来操U\径,从而可以跟t安装程序所需要的路径的变化?br />对于l色软g的制作,其中核心(j)的一点就是获得原来Y件的安装E序所做出的注册表的改变,然后把该变化导出Z个注册表文g. REG来进一步分析。如果导出的.REG文g不包括绝对\径,那么可以把该注册表文件和提取出的软g打包在一起做成绿色Y件。如果导出的.REG文g中包 含当前Y件的l对安装路径Q那么就必须每次都要手工修改注册表中路径Q是很麻?ch)的Q降低了(jin)做成l色软g的意义所在。而?INF文gQ用AddReg命o(h)可以LҎ(gu)的解册个注册表路径的难题?br /> 对于l色软g的安装制作来_(d)最重要的就?1Q也是源文件夹。下面D一个例子:(x) Registry Crawler V4.5 Q是强大的用户和开发者快速定位ƈ配置注册表的工具软g。一个强大的搜烦(ch)引擎允许你基于搜索标准查找注册信息。(可以从天IY件站下蝲http: //www4.skycn.com/soft/2963.htmlQ,安装完成后导出的注册表包含着如下一条语句:(x) [HKEY_LOCAL_MACHINE\SOFTWARE\4Developers\RCrawler\AppPath] @="F:\\tools\\Reg\\RCrawler" 其中“F:\tools\Reg\RCrawler”是安装\径?br />而改写ؓ(f).INF文g是Q?br />[version] Signature="$CHICAGO$" [DefaultInstall] AddReg=Add [Add] HKLM,"SOFTWARE\4Developers\RCrawler\AppPath","",0,"%01%" 注意里面?01%׃表当前的安装路径?br /> 当我们把F:\tools\Reg\RCrawlerq个目录下的文gUd到其他目录时候,要用.REG文g的方式的话,必L工修Ҏ(gu)册表文gQ而?前面?INF文g的时候,什么都无需修改Q只要在文g理器explorer里面Q用鼠标右键执行“安装”命o(h)的时候,%01%p动被替换为当前所?的目录了(jin)? 最后,ȝ一句,注册表文?REG非常方便和直观,但是对于处理路径的变化的情况Q非常笨拙和不方便,?INF不如注册表文件直观,但是可以方便的处理\径信息(包括UNICODE的\径信息)(j)Q所以应该把.REG文g?INF文gl合使用Q互相I补各自的~点?img src ="http://www.shnenglu.com/Walker/aggbug/146850.html" width = "1" height = "1" /> ]]> Driver post-Developement Tech http://www.shnenglu.com/Walker/articles/146849.html漫步者?amp;…?K?/dc:creator>漫步者?amp;…?K?/author>Sat, 21 May 2011 01:16:00 GMT http://www.shnenglu.com/Walker/articles/146849.html http://www.shnenglu.com/Walker/comments/146849.html http://www.shnenglu.com/Walker/articles/146849.html#Feedback 0 http://www.shnenglu.com/Walker/comments/commentRss/146849.html http://www.shnenglu.com/Walker/services/trackbacks/146849.html Driver post-Developement Tech
~译时检?/h3>
使用 /Wall?WX参数~译
/WallQ打开所有的警告
/WXQ将警告视ؓ(f)错误
但是DDK本n的头文g中还包括警告信息Q可使用关闭警告的功能来克服q个问题Q这些警告大多都是由微YҎ(gu)准语a的扩展引L(fng)Q不影响可靠性,我们可以在源文g中关闭这些警告:(x)
MSC_WARNING_LEVEL=/Wall /W4 /WX /wd4115 /wd4127 /wd4200 /wd4201 /wd4214 /wd4255 /wd4514 /wd4619
/wd4668 /wd4820
更好的方法是仅在引vq些警告的MS包含文g部分关闭q些警告Q如下:(x)
Source文g中ؓ(f)Q?
MSC_WARNING_LEVEL=/Wall /WX
使用如下语句包围引v警告的MS包含文gQ?
#pragma warning (disable: 4115 4127 4200 4201 4214 4255 4619 4668 4820)
...
#pragma warning (default: 4115 4200 4214 4255 4619 4668 4820)
注意Q不同DDK版本出现的警告不?
使用C++~译?/h4>
在驱动开发中使用C++?x)带来一些问题,但用C++~译器将有一些额外的好处Q因为C++~译器会(x)做更多的(g)查,使用C开始同时用C++~译器编译的Ҏ(gu)如下Q?
使用/TP~译开养Iq个开兌~译器将.c文g作ؓ(f).cpp文g来编译,q种技术通常在check版本中用,在source文g中需要加入如下代码:(x)
!if !$(FREEBUILD)
USER_C_FLAGS= /TP
!endif
同时Q需要对DriverEntryq行标记Q?
#ifdef __cplusplus
extern "C"
#endif
NTSTATUS DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath);
如果我们使用?jin)WPPQ还需要标记WPP的包含文件?
PREfast
PREfast按照昄规则对代码进行静(rn)态分析(DDK自带Q?
定义DEPRECATE_DDK_FUNCTIONS
在source 文g的C_DEFINES定义DEPRECATE_DDK_FUNCTIONSQ将使编译器在编译是(g)查我们的代码是否使用?jin)DDK已经q时的例E。但?DEPRECATE_DDK_FUNCTIONSq不能检查出所有的q时例程Q唯一的办法是(g)查DDK文档。在驱动中?MmGetSystemRoutineAddress例程可以用来判断我们使用的例E是否还被支持?
使用~译时处?/h4>
C_ASSERT
C_ASSERT是一个编译时断言
条g试
使用#error MSG可以产生一个比C_ASSERT可读性更好的~译旉误:(x)
#define BLK_SHIFT 9
#define BLK_SIZE 512 // Must be 1 << BLK_SHIFT
#if !(BLK_SIZE = (1 << BLK_SHIFT))
#error !(BLK_SIZE == (1 << BLK_SHIFT))
#endif
~译32?amp;64位驱动版?/h4>
~译64位版本可发现如下的问题:(x)
指针问题
使用32位值存储指针、数据结构因为包含指针而改变大?
内联汇编
在驱动中不应该用内联汇~?
~译器差?/h5>
64位结构上的代码兼Ҏ(gu)?
ChkINF
安装前用ChkINF(g)查INF文gQDDK自带Q?
调试?qing)运行时(g)?/h3>
1、用所有的(g)查选项调试
2、逐个关闭(g)查选项调试
3、关闭所有调试选项Q在目标行,使用性能(g)Y件监?
内核调试?/h4>
KDQ命令行调试?
WinDbgQ带有图形前端的调试?
Check版Windows
使用Check版Window调试
驱动验证QDriver VerifierQ?/h4>
d试工具QWindows自带Q,同常讄如下(g)查:(x)
自动(g)查(必选)(j) Ҏ(gu)内存?gu)(g)? IRQL(g)? 内存池跟t? I/O验证 DMA验证 死锁(g)?/li>
其中有一?strong>低资源模?/strong>试在驱动中注入一些资源请求失败错误,q项(g)查应该在排除?jin)其它错误后Q最后来试
调用验证QCUVQ?/h4>
使用调用验证需要更改source文gq新编译驱动:(x)
VERIFIER_DDK_EXTENSIONS=1
CUV支持如下cd的检查:(x)
初始化检查:(x)使用一个内核类型前对其q行验证 一致性检查:(x)(g)查内怾E调用的一致? 分页内存?gu)(g)查:(x)(g)查不正确的分内存(sh)? IRP堆栈(g)查:(x)验证IRP堆栈的?/li>
使用CUV支持~译后的驱动在启动后向调试器报告错误信?
~冲池标?/h4>
~冲池标记可以在分配~冲区前加上4个字W的标记QW(xu)indows2000?qing)XP仅在check版本上打开?jin)缓冲池标记Qfree版本可用gflags /r +ptg命o(h)打开Q?003所有的版本都打开?jin)缓冲池标记。可以通过3U途径来查看这些缓冲池标记Q?
调试? PoolmonQWindows自带Q? PooltagQDDK自带Q?/li>
从XP以后Q我们都应该使用PROTECTED_POOL标记调用ExFreePoolWithTag来释放我们分配的内存Q当驱动验证的特D内存检查开启时Q缓冲池标记不能被开?
代码覆盖
代码覆盖包括行覆盖及(qing)路径覆盖Q可通过如下途径来提高(sh)码覆盖率Q?
试所有有效的h 试所有不正确的输? 使用驱动验证中的低资源模? 随机的注入错?/li>
性能监测
使用KrView?qing)KernRate可以(g)驱动的CPU占用率,我们应该通过两种Ҏ(gu)来测试驱动的负蝲Q?
在整个系l上q行性能监测Q即佉K动负载较大,在整个系l负载中Q它应该只占一个比较小的比? 在驱动上q行性能监测Q分析驱动中最花时间的部分
内核日志
通过Trace ViewQDDK自带Q,我们可以记录9U类型的数据Q?
q程创徏?qing)终? U程创徏?qing)终? 文gI/O 盘I(y)/O 映象文g加蝲?qing)卸? 注册表访?/li>
安装日志
通过使能安装日志Q我们可以跟t驱动在安装时的动作Q在注册表种讄如下键|(x)
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurentVersion\Setup
?x3000FFFF可以使能详细安装日志Q在完成调试后,需要关闭这个日志以保证性能Q日志文件在%systemroot%\setupapi.log
杂项工具
DriverQueryQWindows自带Q:(x)使用q个工具可以查询pȝ中驱动的相关信息 DeviceTreeQ显C备及(qing)驱动的相x(chng)? DevConQ命令行工具Q提供所有设备管理的功能Q部分DriberQuery、DeviceTree功能QDDK的src\setup\devcon有源码,可用于编写驱动控制工? RegEdit32Q注册表~辑工具
诊断
断言
通常使用的断a宏有:
ASSERT ( expression )
ASSERTMSG ( message, expression )
在Win2000以前的系l中,q两个宏不返回Q何?以后的系l中,q两个宏q回expression的?q两个断a仅在check版本中有?通常在如下情况下使用断言:
在进入和退出非?rn)态函数时要对?rn)态数据成员进行检? 在进行一个处理前,校验输入参数是否正确 在进入和退出@环前, 校验输入参数是否正确 在用指针时,Ҏ(gu)针及(qing)指针指向的数据进行校?在用全局变量?对其q行(g)?/li>
校验的方?
除了(jin)(g)查指针是否ؓ(f)NULL?我们q可以做q一步检?例如(g)查数据的cd:
ASSERTMSG ( “Invalid IRP pointer”,
irp != NULL && irp->Type == IO_TYPE_IRP)
(g)查获得的值是否在范围以内 (g)查双向链表的一致?/li>
ASSERTMSG ( “Corrupted List”,
listPtr != NULL && listPtr->Flink != NULL &&
listPtr->Flink->Blink == ListPtr )
ASSERTMSG ( “Invalid Counted String”, string != NULL &&
string->MaxLength > string->Length &&
string != NULL ? (string->Length != 0 ) : TRUE ))
ASSERT ( --CurrentCount > 0 )
p = ExAllocatePoolWithTag ( NonPagedPool, BLK_SIZE, BLK_TAG ); ASSERT ( p != NULL ) 在分配内存时,因ؓ(f)pȝ资源不而引L(fng)分配p|是很正常的事?q里不应该用断a
调试打印
通常使用的调试打印有如下四种:
KdPrint ( format, ... );
KdPrintEx ( componentId, level, format, ... );
DbgPrint ( format, ... );
DbgPrintEx ( componentId, level, format, ... );
头两个调用仅在check版本有效,后两个在所有版本都有效, componentId ?level用来qo(h)调试输出
通常应该打印输出的信息如?
例如用IRP_MJ_CLOSE代替0x2
例如打印出IRP包的d能码
使用标准格式打印 打印调用? 更多的输Z息将有助于调?例如文g?行号,当前执行U程,IRQL
格式化的规则:
如果要打印指?使用%p格式W?q样可以使程序在32位及(qing)64位^C均可q行 如果打印一个计数的字符?使用%Z (ANSI)或?wZ (Unicode),它可以正打印出非空l束的字W串 如果需要打印Unicode?必须认E序q行在DISPATCH_LEVELU别之下 每个输出调用限制?12字节?/li>
WPP软g跟踪
WPP软g提供?jin)一U低开销的日志数据机Ӟ它创Z个二q制数据日志文g存放信息Q它的显著优Ҏ(gu)可以从驱动收集最l用户不可理解的数据?
使用WPP的最单方法是在SOURCE文g中添加如下语句:(x)
RUN_WPP=$(SOURCES) –km
此外Q还需讄一些定义及(qing)包含文gQW(xu)PP的用法如下:(x)
DoTraceMessage(IN TraceFlag, IN Format, ...)
我们也可以通过如下定义WPP转变?sh)试打华ͼ?x)
#define WPP_DEBUG(args) DbgPrint args;
WPP支持一些DbgPrint没有提供的格式符宏?
׃WPP目的Z开销Q所以于调试打印的规则略有不同:(x)
无需数字{换成有意义的字符? 无需输出文g?qing)行h? ……
事g日志
pȝ事g日志用来报告驱动q行q程中发生的事情Q主要是发生的问题,每个日志的大小限制?56字节Q用系l事件日志主要考虑以下四点Q?
pȝ日志的大及(qing)覆盖规则有管理员来指定,驱动加入的每一个事件日志都应当有充分的理由Q管理员q不关系驱动什么时候启动或者关闭,而仅关系驱动发生?jin)什么问?
每个错误指定一个唯一的错误代码,每个事g仅包含错误,便于理员查? 不要全部使用一L(fng)错误信息Q对每个错误使用实际的错误信? 注意消息分类文g的处?/li>
性能监测
一个好的驱动应该给用户提供性能信息Q通常通过WMI来提供这些性能数据Q通常我们可以提供如下数据来衡量驱动的性能Q?
IRP计数 处理数据计数 出错率或者出错个? 安全事g计数
WMI的例子见src\wdm\wmi\wmifilt
自定义信息{?/h4>
驱动可以通过自定义信息{储来提高驱动的调试效率,在Win2000中?strong>KeRegisterBugCheckCallback实现自定义信息{储,在XP?qing)以后的pȝ中?strong>KeRegisterBugCheckReasonCallback实现自定义信息{储?
版本?/h4>
使用版本信息有利于用户报告驱动的问题,在资源描q文件中Q用VERSIONINFO定义来描q驱动的版本信息?
试工具
试的基本原则:(x)
易于复现 易于认试l果 使用不同的^台测? 修复BUG后做回归试
Device Path Exerciser
Device Path ExerciserQdc2.exeQDDK自带Q用不同的讑֤控制I/O调用来检驱动的E_性。这个工L(fng)调用格式如下Q?
dc2 [options] /dr driver [driver …] QXP and later, support to 10 driversQ?
dc2 [options] device Qall, support one dirverQ?
日志部分
dc2.exe׃生四个日志文Ӟ(x)DC2.logQDiags.logQCrashN.logQCrash.log
打开讑֤部分
dc2.exe试图使用多种手段来打开讑֤q行试?
试部分
dc2.exe包括很多试的内容,常用的如下:(x)
PNP驱动试
PNP试Qpnpdtest.exeQDDK自带Q主要包括如下部分:(x)
可移除? 重新分配资源 意外U除讑֤ 压力试Q包?分钟的重新分配资源及(qing)U除试Q最后一个意外移除)(j)
休眠?qing)ACPI试
使用sleeper.exeQDDK自带Q测试驱动的甉|理与系l的甉|理的配合情况,使用pmte.exeQDDK自带Q测试驱动的甉|理功能?
g兼容性测试(HCTQ?/h4>
HCT是一pdWindows Logo Program指定的必通过的测试,它的主要目的是测试硬Ӟ但有助于驱动开发,主要包括如下几类试Q?
Audio
Bus Controllers
Display
Anti-Virus/File System Filter Drivers
Imaging
Input and HID
Modems
Network Devices
Storage Controllers and Devices
Streaming Media and Broadcast
Systems
Unclassified
ȝ
通常Q驱动开发应该遵守以下规则:(x)
使用/Wall, C++~译Q用PREfastQ用DEPRECATE_DDK_FUNCTIONS ?qing)C_ASSERT宏,使用ChkINF(g)查INF文g
使用q行时检查及(qing)日志手段 提供调试诊断信息来快速定位错? 使用HCT?qing)DDK中提供的工具q行试Q用自定义的test caseq行试 ]]> 驱动试工具PnPUtil http://www.shnenglu.com/Walker/articles/146844.html漫步者?amp;…?K?/dc:creator>漫步者?amp;…?K?/author>Fri, 20 May 2011 23:53:00 GMT http://www.shnenglu.com/Walker/articles/146844.html http://www.shnenglu.com/Walker/comments/146844.html http://www.shnenglu.com/Walker/articles/146844.html#Feedback 0 http://www.shnenglu.com/Walker/comments/commentRss/146844.html http://www.shnenglu.com/Walker/services/trackbacks/146844.html PnPUtil (PnPUtil.exe ) is a command line tool that lets an administrator perform the following actions on driver packages :
Adds a driver package to the driver store .
Deletes a driver package from the driver store.
Enumerates the driver packages that are currently in the driver store. Only driver packages that are not in-box packages are listed. An in-box driver package is one which is included in the default installation of Windows or its service packs.
语法Q?nbsp; PnPUtil [/a [/i] InfFileName] [/d [/f] PublishedInfFileName] [/e] [/?] 例子Q?br />C:\>pnputil /a m:\MyDriver.inf C:\>pnputil /e C:\>pnputil /d oem22.inf ]]>【{载】{一内怸IRQL的文章,写得很good http://www.shnenglu.com/Walker/articles/146723.html漫步者?amp;…?K?/dc:creator>漫步者?amp;…?K?/author>Wed, 18 May 2011 23:45:00 GMT http://www.shnenglu.com/Walker/articles/146723.html http://www.shnenglu.com/Walker/comments/146723.html http://www.shnenglu.com/Walker/articles/146723.html#Feedback 0 http://www.shnenglu.com/Walker/comments/commentRss/146723.html http://www.shnenglu.com/Walker/services/trackbacks/146723.html linux的是q程自主性,windows则是对象自主性,其中U程本n也是一个对象,q程也是Q所以一个进E可以操作另外一个进E的地址I间也就不为奇?jin),windows的通信实际上是对象间通信Q而linux因ؓ(f)一切围着q程转,最新的内核中断也被U程化了(jin)Q因此通信是q程间通信Qlinux 中进E作U容器的意义要比windows的更大些Qwindows中进E是一个容器,也是一个对象,某种意义上它作ؓ(f)容器的意义是容纳别的对象?windows的模块化思想更加鲜明?br />windows中将~页Q调度等概念从线E,q程中分,专门安排一个irqlU别来处理之Q而linux下相应的概念则永q和q程相绑定,看看~页中断的处理代码,考虑的一直都是进E的概念Q在windows中,考虑的就是对象的概念?jin),比如文g对象{等Q但是缺|质上真的是和q程相关的,所以在 windows中没有进E?U程上下文的的执行A当然׃能缺了(jin)Q那么谁没有q程/U程上下文呢Q也是ms说的“L上下?#8221;Q?{案?dispatch_level之上Q包括dispatchQ的没有q程/U程上下文,所以,相应U别的执行中׃能访问分内存(可能被换?gu)导致缺늚内存Q了(jin)。windows下进E?U程是和其他对象q列的概念,没有什么特D之处,但是在linuxQunixQ中Q它们却是终极重要的概念Q诏I整个系 l。windowsZ(jin)实现完全异步和ؓ(f)?jin)配合可UL性,一切抽象成?#8220;中断”Q所以我们没有必要特别说什么上下文的概念,上下文只是一个进E?U程?容器Q没有又如何Q代码照h行,之所以强调什么时候要有上下文什么时候没有必要完全是Z(jin)配合q程/U程的,Z(jin)使进E?U程好管理?br />我比较喜Ƣ将一大堆的结果归lؓ(f)一个原因,像一切宏观运动都是牛定律的l果Q一切微观运动都是量子力学的l果Q一切宇观运动都是相对论的结果一P从这一点上看,研究windows是一个好的选择?br />我们看一下两个操作系l的~页Q先说linux? 在linux中,发生~页后执行缺中断处理,当时的上下文q是引v~页的进E线E上下文Q除非当前在中断或Y中断中,然后内核挂v当前U程Q执行磁?ioQ将面取回或者分配一个匿名页面,实际上这里挂起当前线E的意思是执行的缺中断处理ƈ不属于当前线E和在磁盘io或分配匿名页面的q程中可能要{?待,{待意味着U程切换Q一直到U程实际切换Q上下文一直是当前U程上下文?在前面说的中断或软中断中出现~页的话׃能随便进行线E挂起了(jin)Q因为此时是linux唯一可能在Q意上下文的情况,即在内核发生缺也没有关系Q缺?处理只认上下文,不管在什么态(因ؓ(f)内核数据l构常常在中断中被访问,所以,一般还是别在内核用分页内存?sh)(jin),所以linux又规定,内核数据l构?slab或类似的q箋(hu)区分配分配,q且帔R内存Q你完全可以修改内核Q在内核分配一个页面,映射到内核空间或用户I间Q然后修改缺处理程序,使得可以处理映射到内核导致的~页Q最后保证你永远不在中断中访问这个地址Q很ȝ(ch)Q但可能Q)(j)Q所以linux性规定:(x)中断不能引v~页Q原因仅仅一个,上下文不定Q。(附:(x)本质意义上,内核I间q不属于Mq程的地址I间Q只是一个所有进E和资源的管理空_(d)所以内核空间大家公用,所以linux很是巧妙的将物理内存U性映到内核地址I间Q内核数据结构大部分在此分配Q一旦满不?jin)要求,可以从vmalloc区域分配Qƈ且只更新0可E页表,q中?来解军_的进E页表和0可E页表同步问题,所以linux内核I间地址的中断ƈ不需要真正分配内存页面,只需要修改个表p。linux内核I间地址不许~页q没有实质性的规定Q只是ؓ(f)?jin)内核开发的方便Q所以linux仅仅解决用户I间的缺和内核vmalloc表~页。)(j)回到前面正常情况Q在有上 下文的情况下q行盘io或分配匿名页以及(qing)可能引v的当前线E睡眠切换有问题吗?一炚w题(sh)没有Q因为linux/unix量使所有执行A都有特定上下 文,不允许的操作作ؓ(f)E有的特例已经被硬性明文禁止了(jin)Q这L(fng)弊端在于Q留l程序员的只有好好把q个原理研究透或者把那些规定背熟?jin)。在windows?的情况呢Q上下文没有那么Ҏ(gu)?jin),一切都是异步的中断Q很多执行A没有特定上下文,那么发生~页后呢Q可能缺发生在用户U程Q而用L(fng)E运行在被动中断hU别Q这是没有Q何问题的Q所有别的别的执行l都可以中断它,最重要的,io开始例E在dispatchU别q行Q缺处理运行在 dispatchQ调度也q行在dispatch。首先,Z调度在dispatchq行呢?因ؓ(f)在dispatch或之上的执行l就是Q意上下文环境 ?jin),它们是不允许发生U程切换的,q怎么保证呢?如果在dirqlU别的要切换Q那么就要将irql提升到dispatchQ因为当前dirql?dispatch高,于是蓝乎Q如果在dispatch的dpc要调度,那么它要提升irql到dispatchQ因为它已经在了(jin)Q于是亦蓝乎Q这是?因,调度q行在dispatch实际上是Z(jin)保证没有上下文的执行l不能发生线E切换(cLlinuxQlinux中也是没有上下文的不能切换)(j)Q那?io开始ؓ(f)何也在dispatch呢?q是因ؓ(f)windows是异步的Q一个线E发起一个io不一定在当前上下文就可以执行Q可能在一个硬件中断发生后??jin)执行的条gQ考虑irp排队Q,然后此中断派发一个dpc开始io动作Q中断没有确定上下文Q它z֏的dpc同样没有上下文,所以io开始只能在没有?下文的dispatch执行Qio分派例程比如readQwrite之类的必d有上下文的被动别运行,因ؓ(f)它们可能要睡眠,而且不能打扰io开始和完成例程Q现在考虑~页Q看看它能在哪里执行Q咱们从低irql到高考虑Q我们假设被动irql也参与到中断模拟Q如果缺处理运行在最低的被动irqlQ?那么完?jin),试想一个同样在被动irql的线E发生缺,~页q行前必先提升irql到被动别,但是不yQ已l是被动U别?jin),出错Q返回,蓝!但是事实上,被动U别q不参加中断模拟Q这说明~页处理q行在被动别是可以的,但是考虑apcU别Q它可参与中断模拟?jin),apc比被动别高Q于是如果缺处 理在被动U别Q那么apc׃能缺了(jin)Q这说明apc不能用分内存,q很影响大家伙的信心(j)Qwindows怎么能这么限制程序员呢;那么我们将~页处理q行U别往上提高(sh)U,到apcU别Q还是不行,apcq是不能~页Q因为它?yu)是在apcU别的,虚拟中断只能被irql比它高的中断掉;于是再往?赎ͼ到dispatch吧,q下好了(jin)Qapc可以使用分页内存?sh)(jin),但是提升到这个别仅仅?f)?jin)让apc使用分页内存Q如果又引v别的问题Q那么还是别?apc使用分页内存?sh)(jin)。考虑~页需要哪些操作,无非是分配内存面Q或者从盘d|Ӟ考虑后者,肯定要开始一个磁盘ioq程Q而磁盘io是?dispatchq行的,q可以,考虑前者,分配面可能DU程睡眠Q现在缺|在dispatchq行Q想挂v一个线E也没有问题Q正好调度也是在q个U别q行Q仍然没有问题,现在我们可以说缺处理可以在q个U别?jin),但是Qh是贪?j)的Q一些限制L使h能有所创新Q只可惜Q这ơ的创新?windows完美M下失败了(jin)Q我们不甘心(j)dispatch以及(qing)之上的内存(sh)能用分内存,于是再往上提一U,提到哪姑且不考虑Q如?dispatchq种没有上下文的U别产生~页有可能睡眠或请,但是io开始和调度都是定性的在下面的U别q行Q于是不能再往上了(jin)Q就q样?jin),~页中断处理E序只能在dispatchU别q行?br />q下有意思吧Qwindows的大框架已经定死Q不需要硬性规定,一两条原则可以决定这么多事情Q?.中断虚拟化的irql机制使windows成ؓ(f)完全异步os内核Q?.对象化模块化使windows不过分依赖于q程/U程的概念,使得1的实现简单化。网上很多h比如赫赫有名的毛h教授?windows的进E可以操作别的进E空间是windows不安全的原因之一Q我认ؓ(f)q句话没错,但是毛教授似乎没有理解windowsZq么做,它不安全是因为细节没有把握好Q而大的框架我很欣赏,也很坚信Q没有错Qlinux的Y中断和Q务队列就是windows的借鉴Q只可惜Qlinux是善?的,发现工作队列后毅然抛弃了(jin)d队列?br />linux更像是一件艺术作品而windows更像一件工业品。D个例子:(x)一个高大的全钢架结构徏{矗立在q场Q看似永q都没有完过工,巨大的钢架抬?可见Q耗资巨大Q周围只有钢Ӟ没有顶Qh在里面难免风吚w淋,Z?x)在底楼U一间盖好的屋子Q但隑օq(sh)(x)被漏下来的徏{石料将屋顶砸破Q头破血,目前开发商大势已去Q真不知能否完工Q但是框架结构绝对一,~的不是技术,而是Ȁ情;在郊外的草地上,几个满怀Ȁ情的人在自己修徏一座别墅,没有开发商Q?没有望,只有他们自己Q别墅异常豪华,没有什么框Ӟ因ؓ(f)不需要,他们有技术,有激情,~的是大家的支持。前者是windowsQ后者是linuxQ?而unix可能是金字塔吧?br />现在的硬件也在提供更多的功能Q从而一些Y件策略更加容易实玎ͼ比如apic实C(jin)软中断功能,q就更加使得windows的irql如鱼得水?jin),我认为linux马上也将用最新的apic软中断功能来实现softirqQ这一向是linux的作风:(x)l不落伍Q?br />感叹Q现在的g也在来快的发展了(jin)Q快赶超软g发展速度?jin),看,什么都在封装,以前用引脚传递硬件信息,现在用消息了(jin)Q看看pci和pcie吧)(j)Q硬 件和软g都在两极分化Q一帮h搞的东西来简单,傻瓜,另一帮h却越来越高深Q越׃见底Q呜|我,何去何从Q! ]]> IRP的CancelRoutine Q{Q?/title> http://www.shnenglu.com/Walker/articles/146722.html漫步者?amp;…?K?/dc:creator>漫步者?amp;…?K?/author>Wed, 18 May 2011 23:36:00 GMT http://www.shnenglu.com/Walker/articles/146722.html http://www.shnenglu.com/Walker/comments/146722.html http://www.shnenglu.com/Walker/articles/146722.html#Feedback 0 http://www.shnenglu.com/Walker/comments/commentRss/146722.html http://www.shnenglu.com/Walker/services/trackbacks/146722.html 当一个IRP的CancelRoutine没有被设|时QCancelIo操作?x)失败,pȝ中有可能?x)留下永q都不会(x)被complete的IRP。在Threaded IRP和non-threaded IRP一节中我们有谈到irp分ؓ(f)U程相关和非U程相关两种。倘若一个永q不complete的irp是非U程相关的,情况?x)稍微好一点,多pȝ中泄露了(jin)一个资源。倘若该irp是线E相关的Q那事情大?jin)。thread IRP由IoManager生成q保留在U程的IRP队列里,负责处理该IRP的驱动在收到下层驱动的Complete事g后不?x)主动收回IRP的资源而是l箋(hu)completelIoManagerQ由IoManager负责回收Qƈ从线EIRP列表中删除该IRP。一个线E在退出前?x)遍历等待IRP队列里所有的IRPQ直到它们全部被complete为止。倘若其中有一个irp永远不completeQ那么线E就永远不退出,无论是ExitThread也好q是_endthreadex也好q是什么邪恶的暴力擦除数据强退也好Q全都不用。线E不退出,q程也不能销?题外话:(x)q程资源的回收动作由最后一个线E退出后发vQ所谓的杀q程Q其实是用apcl所有线E发起退出操作)(j)。更p糕的是Q操作系l的x(chng)q程都会(x)被堵住,除了(jin)关电(sh)源,没有其他办法恢复Q这一点简直比BSODq糟p。我们知道由user mode发v的IO操作最后都?x)翻译成threaded irpQ这是Z么我?.1大谈特谈user modeU程的原因:(x)q个陷阱quser modeE序也会(x)掉进厅RBad dog! 要解册一Ҏ(gu)法很单目标很明确Q那是防止“永远不complete的irp”q种东西出现。一般的做法是加个线E或者timerq设|超时时_(d)旉一到就cancelq个irp。如果irp由user modeE序发vQ那么就调用CancelIoQ如果irp由驱动发P则是调用IoCancelIrp。所有这些动作要生效的大前提是你的irp有CancelRoutine的存在,否则一切都是白搭。所以这里我有个l验要跟大家分nQ?span style="color: #0000ff">M时候都l你的irp讄CancelRoutineQƈ在CancelRoutine里Complete你的IRP!为方便v见我们选non-threaded irp做个例子Q所有的代码都在内核态,免得各位看官看示例代码还要做上下文切换?br />
通过实验,我现在已基本搞清?jin)原? 与大家交? 1.普通WIN32用户态程序与驱动E序交互: (1).当用L(fng)序打开讑֤? IO理器向驱动E序发IRP_MJ_CREATE. (2) 用户E序退出时,不论此时是否有未完成的IRP, IO理器都?x)首先向驱动发IRP_MJ_CLEANUP. (3) 如果在发送了(jin)IRP_MJ_CLEANUP之后,仍有未完成的IRP(例如驱动E序未提供CleanUp例程或在CleanUp例程中未清除所有未完成的IRP,׃(x)造成q种情况), 则IO理器会(x)依次调用q些IRP的OnCancel例程(如果驱动E序既未提供CleanUp例程又未挂接Cancel例程q?q些IRP无法得到清?.最?IO理器向驱动发IRP_MJ_CLOSE. 2.上层驱动E序与下层驱动程序的交互. (1).当上层驱动调用IoGetDeviceObjectPointer()?该函C(x)向下层驱动发送IRP_MJ_CREATE和IRP_MJ_CLEANUP. (2).当上层驱动调用ObDereferenceObject()?该函数只?x)向下层驱动发送IRP_MJ_CLOSE. 3.故障原因: 我的上层驱动在Unload例程中调用了(jin)ObDereferenceObject(), 但是׃仍有未完成的IRP,因此即我的上层驱动卸蝲?但这些IRP仍然留在下层驱动E序的队列中未得到清?以后当下层驱动一旦去完成q些IRP时就?x)造成BUG_CHECK, 因ؓ(f)IRP中的FileObject域指的文件对象已不存?
dazzy
2001-07-27 08:45
分析透彻Q一般的驱动都要注册q实现CLEANUP的dispatch.
]]> 驱动E序与应用程序的接口 http://www.shnenglu.com/Walker/articles/146721.html漫步者?amp;…?K?/dc:creator>漫步者?amp;…?K?/author>Wed, 18 May 2011 23:26:00 GMT http://www.shnenglu.com/Walker/articles/146721.html http://www.shnenglu.com/Walker/comments/146721.html http://www.shnenglu.com/Walker/articles/146721.html#Feedback 0 http://www.shnenglu.com/Walker/comments/commentRss/146721.html http://www.shnenglu.com/Walker/services/trackbacks/146721.html WDM驱动E序与应用程序的接口
1. 2. WDM的安全,也保证安全地创徏一个惟一的、独立于语言的访问设备的Ҏ(gu)?/span>
来调用设备。在某个 Win32 APIs用符号链打开一个设备的句柄
?/span>, GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL ,NULL );
?/span>CreateLink中的W一个参C?/span>Windows 98/2000文g )产生驱动E序Q它通常使用c?/span>KunitizedName。例如:(x)如果链接名称的主q是 L”那么?/span>CreateFileQ第六个参数 (Flags)?/span>
使用一个输出接口打开句柄
库提供两个助手类来获得对该接口的访问容易一些,q两个类?/span>CDeviceInterface, ?/span>
CdeviceInterfaceClasscȝ一个实例来获得一个或更多?/span>CdeviceInterfacecL一个单一讑֤接口的抽象。它的成员函?/span>DevicePath()中用来打开讑֤?/span>
<< DevInterface.DevicePath() << endl; HANDLE hDev; hDev = CreateFile( DevInterface.DevicePath(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if (hDev == INVALID_HANDLE_VALUE) *pError = GetLastError(); return hDev; }
在设备中执行 I/O 操作
来生到讑֤对象?/span>IRPs
Win32 API
DRIVER_FUNCTION_xxx IRP_MJ_xxx
KDevice subclass member function
CreateFile
CREATE
Create
ReadFile
READ
Read
WriteFile
WRITE
Write
DeviceIoControl
DEVICE_CONTROL
DeviceControl
CloseHandle
CLOSE CLEANUP
Close CleanUp
?/span>CleanUp使内ؓ(f)讑֤创徏一个新的文件对象。这使得多个句柄可以映射同一个文件对象。当q个文g对象的最后一个用L(fng)句柄被撤销后, I/O。当没有M用户U和核心(j)U的Ҏ(gu)件对象的讉K的时候, I/O?/span>
引起错误(无效功能Q?/span>
~写?/span>VxD属性。在 Windows NT/2000I/O?/span>WriteFile参数转换?/span>IRP标志Q?/span>I/O锁住在存储器中,q且创徏?jin)一个存储在 IRP域。一个设备可以通过调用 Kirp::Mdl?/span>
标志Q设备对象分别通过 KIrp::BufferedReadDest或写操作获得 buff标志也不讄 DO_DIRECT_IO?/span>UserBuffer?/span>WriteFile参数。然而,存储区ƈ没有被锁住而且地址只对调用q程有效。驱动程序可以?/span>KIrp::UserBuffer域?/span>
调用Q?/span>buffer控制代码Q它不在讑֤对象的特性中。宏 CTL_CODE中定义)(j)用来构造控制代码。这个宏的其中一个参数指明缓冲方法是 METHOD_BUFFERED, METHOD_IN_DIRECT, METHOD_OUT_DIRECT, 。下面的表显CZ(jin)q些Ҏ(gu)和与之对应的能获得输入缓冲与输出~冲?/span>KIrp
Method
Input Buffer Parameter
Output Buffer Parameter
METHOD_BUFFERED
KIrp::IoctlBuffer
KIrp::IoctlBuffer
METHOD_IN_DIRECT
KIrp::IoctlBuffer
KIrp::Mdl
METHOD_OUT_DIRECT
KIrp::IoctlBuffer
KIrp::Mdl
METHOD_NEITHER
KIrp::IoctlType3InputBuffer
KIrp::UserBuffer
Q系l分配一个单一的缓冲来作ؓ(f)输入与输出。驱动程序必d向输出缓冲放数据之前拯输入数据。驱动程序通过调用 KIrp::IoctlBuffer理器从pȝ~冲拯数据到提供给 Ring 3?/span>Information?/span>METHOD_OUT_DIRECT的参数呈C同的含义。参?/span>InputBuffer。参?/span>OutputBuffer对象Q驱动程序对q个对象的访问通过调用 KIrp::MdlQ调用者必L对缓冲的写访问权限?/span>
Q内核只提供虚拟地址Q它不会(x)做映来配置~冲。虚拟地址只对调用q程有效?/span>
的例子:(x)
来定义一?/span>IOCTL#define IOCTL_MYDEV_GET_FIRMWARE_REV "
CTL_CODE (FILE_DEVICE_UNKNOWN,0,METHOD_BUFFERED,FILE_ANY_ACCESS)
调用Q?/span>
BOOLEAN b; CHAR FirmwareRev[60]; ULONG FirmwareRevSize; b = DeviceIoControl(hDevice, IOCTL_MYDEV_GET_VERSION_STRING, NULL, // no input q里?/span>output如果输出~冲_大,讑֤拯串到里面q将拯的资l束讄?/span>FirmwareRevSize在驱动程序中Q代码看h如下所C:(x)
const char* FIRMWARE_REV = "FW 16.33 v5"; NTSTATUS MyDevice::DeviceControl( KIrp I ) { ULONG fwLength=0; switch ( I.IoctlCode() ) { case IOCTL_MYDEV_GET_FIRMWARE_REV: fwLength = strlen(FIRMWARE_REV)+1; if (I.IoctlOutputBufferSize() >= fwLength) { strcpy((PCHAR)I.IoctlBuffer(),FIRMWARE_REV); I.Information() = fwLength; return I.Complete(STATUS_SUCCESS); } else
{ } case . . . } }
]]> WDFREQUEST http://www.shnenglu.com/Walker/articles/146686.html漫步者?amp;…?K?/dc:creator>漫步者?amp;…?K?/author>Wed, 18 May 2011 11:11:00 GMT http://www.shnenglu.com/Walker/articles/146686.html http://www.shnenglu.com/Walker/comments/146686.html http://www.shnenglu.com/Walker/articles/146686.html#Feedback 0 http://www.shnenglu.com/Walker/comments/commentRss/146686.html http://www.shnenglu.com/Walker/services/trackbacks/146686.html 1 Request q入队列之后是不能complte的,必须从Queue当中取出再Complete ]]> windbg http://www.shnenglu.com/Walker/articles/146523.html漫步者?amp;…?K?/dc:creator>漫步者?amp;…?K?/author>Mon, 16 May 2011 13:47:00 GMT http://www.shnenglu.com/Walker/articles/146523.html http://www.shnenglu.com/Walker/comments/146523.html http://www.shnenglu.com/Walker/articles/146523.html#Feedback 0 http://www.shnenglu.com/Walker/comments/commentRss/146523.html http://www.shnenglu.com/Walker/services/trackbacks/146523.html 阅读全文 ]]> inf文g分析 http://www.shnenglu.com/Walker/articles/146269.html漫步者?amp;…?K?/dc:creator>漫步者?amp;…?K?/author>Thu, 12 May 2011 10:54:00 GMT http://www.shnenglu.com/Walker/articles/146269.html http://www.shnenglu.com/Walker/comments/146269.html http://www.shnenglu.com/Walker/articles/146269.html#Feedback 0 http://www.shnenglu.com/Walker/comments/commentRss/146269.html http://www.shnenglu.com/Walker/services/trackbacks/146269.html ;/*++
;
;Copyright (c) 1990-1999 Microsoft Corporation All rights Reserved
;
;Module Name:
;
; STATBUS.INF
;
;Abstract:
; INF file for installing toaster bus enumerator driver
;
;Installation Notes:
; Using Devcon: Type "devcon install statbus.inf root\statbus" to install
;
;--*/
;Version 节出现在 inf 中的W一个位|,每个 inf 文g都必L?/span>
[Version]
; 指明那个pȝ上这?/span>inf 是有效的
Signature="$WINDOWS NT$"
; 标准讑֤cȝ名字Q在 devguid.h 中有定义Q最好同时提?/span>ClassGuid Q方便系l查找?/span>
如果定义新的讑֤c?/span>, 那么必须使用新的名字 , ?/span>GUID.
Class=System
; pȝcȝ GUID
ClassGuid={4D36E97D-E325-11CE-BFC1-08002BE10318}
; 指定 inf 文g的提供?/span>
Provider=%MSFT%
; 驱动版本信息
DriverVer=05/10/2011 ,6.1.7600.16385
指定驱动E序包含的在安装包中?/span>catalog 文g。这?/span> 文g?/span>WQHL 提供?/span>
CatalogFile=KmdfSamples.cat
Q指定了(jin)驱动文g被拯到哪?/span>
01
SourceDrive :\ pathname (the directory from which the INF file was installed)
10
Windows directory This is equivalent to %windir% .
11
System directory This is equivalent to %windir% \ system32 for NT-based systems, and to %windir% \ system for Windows 9x/Me.
12
Drivers directory This is equivalent to %windir% \ system32 \ drivers for NT-based platforms, and to %windir% \ system \ IoSubsys on Windows 9x/Me platforms.
17
INF file directory
18
Help directory
20
Fonts directory
21
Viewers directory
23
Color directory (ICM) (not used for installing printer drivers)
24
Root directory of the system disk. This is the root directory of the disk on which Windows files are installed. For example, if dirid 10 is "C:\winnt ", then dirid 24 is "C:\ ".
25
Shared directory
30
Root directory of the boot disk, also known as "ARC system partition," for NT-based systems. (This might or might not be the same directory as the one represented by dirid 24.)
50
System directory for NT-based operating systems This is equivalent to %windir% \ system (NT-based systems only).
51
Spool directory (not used for installing printer drivers − see Printer Dirids )
52
Spool drivers directory (not used for installing printer drivers)
53
User profile directory
54
Directory where ntldr.exe and osloader.exe are located (NT-based systems only)
55
Print processors directory (not used for installing printer drivers)
-1
Absolute path
[DestinationDirs]
DefaultDestDir = 12
Q指定用什么分发媒体?/span>
[SourceDisksNames]
diskid = disk-description [, [tag-or-cab-file ], [unused , path ], [flags ][, tag-file ]] Windows XP and later
如果有多个地方,需要指?/span> 1 Q?/span> 2 Q?/span> 3 Q?/span> 4 Q。。?/span>
1 = %DiskId1%,,,""
Q指定文件在那个分发媒体上?/span>
[SourceDisksFiles]
statbus.sys = 1,,
;*****************************************
; ToasterStatBus Install Section
;*****************************************
Q?/span>Manufacturer 章节用于识别q样一些厂商,该厂商的一个或者多个设备能够用该 inf 文gq行安装?/span>
[Manufacturer] manufacturer-identifier [manufacturer-identifier ] [manufacturer-identifier ]
manufacturer-identifier 如下表示Q?/span>
manufacturer-name |% strkey% =models-section-name |% strkey% =models-section-name [, TargetOSVersion ] [, TargetOSVersion ] ... (Windows XP and later versions of Windows)
该条目确定设备的厂商Qƈ且在 inf 文g中必L一个相应的同样的名字的 Models 章节?/span>
[Manufacturer]
%StdMfg%=Standard,NTx86
; For Win2K because it cannot parse decorated sections.
[Standard]
;
; These are the toaster bus pnp ids
; ToasterStatBus.DeviceDesc 是设备描q?/span>
Q?/span>ToasterStatBus_Device ?/span>install-section-name
; root\statbus 是硬?/span>ID
g ID 有以下一些格式?/span>
enumerator \ enumerator-specific-device-id
Is the typical format for individual PnP devices reported to the PnP manager by a single enumerator. For example, USB\VID_045E&PID_00B identifies the Microsoft HID keyboard device on a USB bus. Depending on the enumerator, such a specification can even include the device's hardware revision number as, for example, PCI\VEN_1011&DEV_002&SUBSYS_00000000&REV_02.
* enumerator-specific-device-id
Indicates with the asterisk (* ) that the device is supported by more than one enumerator. For example, *PNP0F 01 identifies the Microsoft serial mouse, which also has a compatible-id specification of SERENUM\PNP0F 01.
device-class-specific-ID
Is an I/O bus-specific format, as described in the hardware specification for the bus, for the hardware IDs of all peripheral devices on that type of I/O bus.
%ToasterStatBus.DeviceDesc%=ToasterStatBus_Device, root\statbus
; For XP and later
[Standard.NTx86]
%ToasterStatBus.DeviceDesc%=ToasterStatBus_Device, root\statbus
[ToasterStatBus_Device.NT]
CopyFiles=Drivers_Dir
[ToasterStatBus_Device.NT.HW]
AddReg=ToasterStatBus_Device.NT.AddReg
[ToasterStatBus_Device.NT.AddReg]
HKR,,DeviceCharacteristics,0x10001,0x0100 ; Use same security checks on relative opens
HKR,,Security,,"D:P(A;;GA;;;BA)(A;;GA;;;SY)" ; Allow generic-all access to Built-in administrators and Local system
[Drivers_Dir]
statbus.sys
;-------------- Service installation
[ToasterStatBus_Device.NT.Services]
AddService = statbus,%SPSVCINST_ASSOCSERVICE%, Statbus_Service_Inst
; -------------- statbus driver install sections
[Statbus_Service_Inst]
DisplayName = %statbus.SVCDESC%
ServiceType = 1 ; SERVICE_KERNEL_DRIVER
StartType = 3 ; SERVICE_DEMAND_START
ErrorControl = 1 ; SERVICE_ERROR_NORMAL
ServiceBinary = %12%\statbus.sys
LoadOrderGroup = Extended Base
;
;--- ToasterStatBus_Device WDF Coinstaller installation ------
;
[DestinationDirs]
ToasterStatBus_Device_CoInstaller_CopyFiles = 11
[ToasterStatBus_Device.NT.CoInstallers]
AddReg=ToasterStatBus_Device_CoInstaller_AddReg
CopyFiles=ToasterStatBus_Device_CoInstaller_CopyFiles
[ToasterStatBus_Device_CoInstaller_AddReg]
HKR,,CoInstallers32,0x00010000, "WdfCoInstaller01009.dll,WdfCoInstaller"
[ToasterStatBus_Device_CoInstaller_CopyFiles]
WdfCoInstaller01009.dll
[SourceDisksFiles]
WdfCoInstaller01009.dll=1 ; make sure the number matches with SourceDisksNames
[ToasterStatBus_Device.NT.Wdf]
KmdfService = statbus, statbus_wdfsect
[statbus_wdfsect]
KmdfLibraryVersion = 1.9
[Strings]
SPSVCINST_ASSOCSERVICE= 0x00000002
MSFT = "Microsoft"
StdMfg = "(Standard system devices)"
DiskId1 = "Toaster Static Bus Installation Disk #1"
ToasterStatBus.DeviceDesc = "Toaster Static Bus Enumerator"
statbus.SVCDESC = "Toaster Static Bus Enumerator"
]]> 如何强制生成dump文g http://www.shnenglu.com/Walker/articles/133574.html漫步者?amp;…?K?/dc:creator>漫步者?amp;…?K?/author>Sun, 14 Nov 2010 01:14:00 GMT http://www.shnenglu.com/Walker/articles/133574.html Windows 包含一U功能,可以用来?j)ɾpȝ停止响应q生成内存{储文?(Memory.dmp)。在(zhn)执行此操作Ӟ可能?x)收C条类g下内容的 Stop 错误消息Q?
*** STOP:0x000000E2 (0x00000000,0x00000000,0x00000000,0x00000000) The end-user manually generated the crashdump.
启用此功能后Q按住右 Ctrl 键,同时?Scroll Lock 键两ơ,卛_生成一个内存{储文件。此功能适用?PS/2 键盘和通用串行ȝ (USB) 键盘。PS/2 键盘?sh)用键盘自带?i8042prt.sys 驱动E序。但是,对于 USB 键盘Q则必须?Kbdhid.sys 驱动E序安装一个修补程序。有x(chng)修补E序的更多信息,请参?#8220;更多信息”部分末尾?#8220;Windows Server 2003 解决Ҏ(gu)”节?br>注意 Q允怋?USB 键盘生成内存转储q程?Kbdhid.sys 驱动E序存在一定局限性。这是Q当计算机在高(sh)断请求?(IRQL) 停止响应ӞCtrl+Scroll Lock+Scroll Lock 键盘快捷方式不v作用。之所以存在此局限性是因ؓ(f)?i8042prt.sys 驱动E序相比QKbdhid.sys 驱动E序q行时的 IRQL 较低。此 USB 键盘功能只在q行 Microsoft Windows Server 2003 的计机上v作用?
更多信息
警告Q如果用注册表~辑器或其他Ҏ(gu)错误C改了(jin)注册表,则可能会(x)出现严重问题。这些问题可能需要重新安装操作系l才能解冟뀂Microsoft 不能保证可以解决q些...
警告 Q如果用注册表~辑器或其他Ҏ(gu)错误C改了(jin)注册表,则可能会(x)出现严重问题。这些问题可能需要重新安装操作系l才能解冟뀂Microsoft 不能保证可以解决q些问题。修Ҏ(gu)册表需要?zhn)自担风险?br>
默认情况下,用此功能。要在?PS/2 键盘的计机上启用此功能Q需按本文中的说明修Ҏ(gu)册表Q然后重新启动计机。在重新启动计算机后Q按?Ctrl 键,同时?Scroll Lock 键两ơ,卛_生成一?Memory.dmp 文g。必M用空格键右侧?Ctrl 键。在使用 USB 键盘的计机上,不必重新启动计算机。只需拔掉键盘然后再将它重新插上。然后,便能生成 Memory.dmp 文g?br>
要在使用 PS/2 键盘的计机上启用此功能Q请按照下列步骤操作Q?
启动注册表编辑器?
扑ֈ以下注册表子:(x)
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\i8042prt\Parameters
?#8220;~辑”菜单上,单击“d?#8221;Q然后添加以下注册表:(x)
名称 QCrashOnCtrlScroll数据cd QREG_DWORD?/strong>Q?
退出注册表~辑器,然后重新启动计算机?
要在使用 USB 键盘的计机上启用此功能Q需安装“更多信息”部分末尾?#8220;Windows Server 2003 解决Ҏ(gu)”节中提到的修补E序?br>
要确保在使用 USB 键盘的计机上启用此功能Q请按照下列步骤操作Q?
启动注册表编辑器?
扑ֈ以下注册表子:(x)
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\kbdhid\Parameters
保启用?jin)以下注册表?x)
名称 QCrashOnCtrlScroll数据cd QREG_DWORD?/strong>Q?
退出注册表~辑器?
如何选择内存转储文g选项
可以生成三种cd的内存{储文件。在手动触发转储文g前,先选择该文件。ؓ(f)此,h照下列步骤操作:(x)
右键单击“我的?sh)?#8221;Q然后单?#8220;属?#8221;?
单击“高”选项卡,然后单击“启动和故障恢?#8221;按钮?
单击“写入调试信息”Q然后单M选中“完全内存转储”?#8220;核心(j)内存转储”?#8220;内存{?#8221;?
有关内存转储文g选项的更多信息,请单M面的文章~号Q以查看 Microsoft 知识库中相应的文章:(x)
254649 (http://support.microsoft.com/kb/254649/ ) Windows Server 2003、Windows XP ?Windows 2000 内存转储文g选项概述
注意 Q如果服务器中有像某?Compaq 计算Z所h?#8220;自动pȝ重启”(ASR) q样的功能,L(fng)用它。因功能?x)中断{储过E。在 Compaq 计算ZQ?zhn)可以通过修改基本输入/输出pȝ (BIOS) 讄来禁?ASR 功能?br>
注意 Q在h 2 GB 或更?RAM 的计机上,不能q行完全内存转储。要限制 Windows 2000 可以讉K的内存,请向 Boot.ini 文g中添?<MaxMem=2000> 参数?br>
如果已经安装?Microsoft 知识库文?835732 中描q的安全更新Q或安装?jin)包含此安全更新?Service PackQ请查看下面?Microsoft 知识库文章:(x)
885117 (http://support.microsoft.com/kb/885117/ ) “启动和故障恢?#8221;中显C?#8220;核心(j)内存转储”Q但?Windows 2000 ?Windows Server 2003 中执行完全内存{?
有关更多信息Q请单击下面的文章编P以查?Microsoft 知识库中相应的文章:(x)
835732 (http://support.microsoft.com/kb/835732/ ) MS04-011QMicrosoft Windows 安全更新
Service Pack 信息
要解x(chng)问题Q请获取最新的 Windows Server 2003 Service Pack。有x(chng)多信息,请单M面的文章~号Q以查看 Microsoft 知识库中相应的文章:(x)
889100 (http://support.microsoft.com/kb/889100/ ) 如何获取最新的 Windows Server 2003 Service Pack
修补E序信息
Microsoft 现在提供?jin)一个受支持的修补程序,但是Q此修补E序仅用于修复本文所q的问题。请仅将此修补程序应用于出现q一特定问题的系l。此修补E序可能q(sh)(x)接受q一步的试。因此,如果q个问题没有Ҏ(gu)造成严重影响Q我们徏议?zhn){待包含此修补程序的下一?Windows Server 2003 Service Pack?br>
要解x(chng)问题Q请?Microsoft 在线客户服务提交h以获取该修补E序。要提交联机h以获取该修补E序Q请讉K下面?Microsoft |站Q?
注意 Q如果发生其他问题或需要进行Q何疑难解{,则?zhn)可能需要创建单独的服务h。对于此特定修补E序无法解决的其他支持问题和事项Q将照常收取支持费用。要创徏单独的服务请求,误问下面的 Microsoft |站Q?
先决条g
要应用此修补E序Q必d计算Z安装 Windows Server 2003 ?Windows Server 2003 Service Pack 1?
重新启动要求
应用此修补程序后Q必重新启动计机?
修补E序替代信息
此修补程序不替代M其他修补E序?
文g信息
此修补程序的英文版具有下表中列出的文件属性(或更新的文g属性)(j)。这些文件的日期和时间按协调世界?(UTC) 列出。当(zhn)查看文件信息时Q该旉{换ؓ(f)本地旉。要?jin)?UTC 与本地时间之间的时差Q请使用“控制面板”?#8220;日期和时?#8221;的“时区”选项卡?
Windows Server 2003Q基?x86 ?32 位版本)(j)
收v该表?/span> 展开该表?/span>
文g?/th>
文g版本
文g大小
日期
旉
q_
SP 要求
服务分支
Kbdhid.sys
5.2.3790.493
16,896
28-Feb-2006
00:03
x86
?/td>
RTMQFE
Kbdhid.sys
5.2.3790.2649
17,408
28-Feb-2006
03:11
x86
SP1
SP1QFE
Windows Server 2003Q基?x64 的版本)(j)
收v该表?/span> 展开该表?/span>
文g?/th>
文g版本
文g大小
日期
旉
q_
Kbdhid.sys
5.2.3790.2649
24,576
13-Apr-2006
15:59
x64
Windows Server 2003Q基?Itanium 的版本)(j)
收v该表?/span> 展开该表?/span>
文g?/th>
文g版本
文g大小
日期
旉
q_
SP 要求
服务分支
Kbdhid.sys
5.2.3790.493
47,104
13-Apr-2006
15:54
IA-64
?/td>
RTMQFE
Kbdhid.sys
5.2.3790.2649
49,664
13-Apr-2006
15:59
IA-64
SP1
SP1QFE
有关更多信息Q请单击下面的文章编P以查?Microsoft 知识库中相应的文章:(x)
928839 (http://support.microsoft.com/kb/928839/ ) 如何使用键盘?Virtual Server 2005 来宾计算Z生成内存转储文g
配置注册表项以生成内存{储文?/h3>
可以在以下注册表子项下配|相应项以生成内存{储文Ӟ(x)
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\i8042prt\crashdump
REG_DWORD 如下所C:(x)
Dump1Keys Dump2Key
Dump1Keys Ҏ(gu)要用的修改键的位图。其值包括:(x)
#define CRASH_R_SHIFT 0x01 #define CRASH_R_CTRL 0x02 #define CRASH_R_ALT 0x04 #define CRASH_L_SHIFT 0x10 #define CRASH_L_CTRL 0x20 #define CRASH_L_ALT 0x40
Dump2Key Ҏ(gu)键盘布局扫描码表中的索引。下面是驱动E序中的实际表?br>注意 Q烦(ch)?124 (sysreq) 是一U特D情形,因ؓ(f)一?84 键的键盘h不同的扫描码?
const UCHAR keyToScanTbl[134] = {
0x00,0x29,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
0x0A,0x0B,0x0C,0x0D,0x7D,0x0E,0x0F,0x10,0x11,0x12,
0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x00,
0x3A,0x1E,0x1F,0x20,0x21,0x22,0x23,0x24,0x25,0x26,
0x27,0x28,0x2B,0x1C,0x2A,0x00,0x2C,0x2D,0x2E,0x2F,
0x30,0x31,0x32,0x33,0x34,0x35,0x73,0x36,0x1D,0x00,
0x38,0x39,0xB8,0x00,0x9D,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xD2,0xD3,0x00,0x00,0xCB,
0xC7,0xCF,0x00,0xC8,0xD0,0xC9,0xD1,0x00,0x00,0xCD,
0x45,0x47,0x4B,0x4F,0x00,0xB5,0x48,0x4C,0x50,0x52,
0x37,0x49,0x4D,0x51,0x53,0x4A,0x4E,0x00,0x9C,0x00,
0x01,0x00,0x3B,0x3C,0x3D,0x3E,0x3F,0x40,0x41,0x42,
0x43,0x44,0x57,0x58,0x00,0x46,0x00,0x00,0x00,0x00,
0x00,0x7B,0x79,0x70 };
本文中提到的W三方品由 Microsoft 以外的其他公司提供。对于这些品的性能或可靠性,Microsoft 不作M暗示保证或其他Ş式的保证?/div>
]]>Q{Q调试笔讎ͼ(x)pȝ挂在DPCQ上Q? http://www.shnenglu.com/Walker/articles/133573.html漫步者?amp;…?K?/dc:creator>漫步者?amp;…?K?/author>Sun, 14 Nov 2010 00:59:00 GMT http://www.shnenglu.com/Walker/articles/133573.html http://www.shnenglu.com/Walker/comments/133573.html http://www.shnenglu.com/Walker/articles/133573.html#Feedback 0 http://www.shnenglu.com/Walker/comments/commentRss/133573.html http://www.shnenglu.com/Walker/services/trackbacks/133573.html 调试W记Q系l挂在DPCQ上Q?
q是发生在我的笔记本?sh)脑上的一ơ系l挂死,发生在唤醒过E中Q屏q没有Q何显C,因ؓ(f)我的?sh)脑始终是启用通过热键QCtrl+ScrollLockQ来触发蓝屏的,所以可以通过热键触发蓝屏和生{储?/p>
以下是分析{储文件的要过E,转储的类型是内核转储。系l中只有一个CPU?/p>
kd> !cpuinfo CP F/M/S Manufacturer MHz PRCB Signature MSR 8B Signature Features 0 6,13,8 GenuineIntel 1862 0000002000000000 a0033fff Cached Update Signature 0000002000000000 Initial Update Signature 0000002000000000
操作pȝ是XP SP2Q?/p>
kd> version Windows XP Kernel Version 2600 (Service Pack 2) UP Free x86 compatible Product: WinNt, suite: TerminalServer SingleUserTS Built by: 2600.xpsp_sp2_qfe.070227-2300
执行!pcr命o(h)观察CPU的控制区Q?/p>
kd> !pcr KPCR for Processor 0 at ffdff000: Major 1 Minor 1 NtTib.ExceptionList: 80548fec NtTib.StackBase: 805492f0 NtTib.StackLimit: 80546500 NtTib.SubSystemTib: 00000000 NtTib.Version: 00000000 NtTib.UserPointer: 00000000 NtTib.SelfTib: 00000000
SelfPcr: ffdff000 Prcb: ffdff120 Irql: 00000000 IRR: 00000000 IDR: ffffffff InterruptMode: 00000000 IDT: 8003f400 GDT: 8003f000 TSS: 80042000
CurrentThread: 80551d20 NextThread: 89b512e8 IdleThread: 80551d20
DpcQueue: 0x80552380 0x804ff5b8 [Normal] nt!KiTimerExpiration 0x8abcfed4 0xba7843e8 [Normal] ACPI!ACPIInterruptServiceRoutineDPC 0x8a6560cc 0xba50fdf0 [Normal] NDIS!ndisMDpcX 0x8a899eec 0xbaa28650 [Normal] i8042prt!I8042KeyboardIsrDpc 0x8a899e90 0xbaa2b0ef [Normal] i8042prt!I8xKeyboardSysButtonEventDpc 0x8a899dd0 0xbaa2a163 [Normal] i8042prt!I8042ErrorLogDpc 0xb87ffa4c 0xb87e8020 [Normal] SynTP 0xb87ffa24 0xb87e7f60 [Normal] SynTP
昄QDPCQDeferred Procedure Call Q队列中有不Q务等待执行,q是pȝ挂死的一个典型症状。DPC是Windowspȝ中一U极光要的机制QDPCd在DISPATCH_LEVEL执行Q高?sh)用来执行普通线E的PASSIVE_LEVEL。这意味着Q如果一个CPU的DPC队列中有dQ那么这个CPU׃?x)去执行普通的U程。如果长旉保持q种状态,那么pȝ便会(x)表现出挂ȝ症状——界面没有刷斎ͼH口不听使唤?/p>
仔细观察上面昄的DPC队列Q第一列是DPC对象的地址Q也是KDPCl构的地址Q第二列是这个DPC的对应函敎ͼ带方括号的第三列是DPC的状态,W四列是DPC函数的符可C?/p>
可以使用dt命o(h)来显CDPCl构Q?/p>
kd> dt _KDPC 0x80552380 nt!_KDPC +0x000 Type : 19 +0x002 Number : 0 '' +0x003 Importance : 0x1 '' +0x004 DpcListEntry : _LIST_ENTRY [ 0x8abcfed8 - 0xffdff980 ] +0x00c DeferredRoutine : 0x804ff5b8 void nt!KiTimerExpiration+0 +0x010 DeferredContext : (null) +0x014 SystemArgument1 : 0x007af640 +0x018 SystemArgument2 : (null) +0x01c Lock : 0xffdff9c0 -> 0
有这么多DPCdQ那么当前CPU按理说要么应该在执行某个DPCQ要么应该在执行更高?sh)先U的中断d。不妨观察一下栈回溯Q?/p>
kd> kvn # ChildEBP RetAddr Args to Child 00 80548f98 baa2a7fa 000000e2 00000000 00000000 nt!KeBugCheckEx+0x1b (FPO: [5,0,0]) 01 80548fb4 baa2a032 00899d40 01ffffc6 00000000 i8042prt!I8xProcessCrashDump+0x237 (FPO: [3,0,0]) 02 80548ffc 80540add 89d6cd98 8a899c88 00010009 i8042prt!I8042KeyboardInterruptService+0x21c (FPO: [Non-Fpo]) 03 80548ffc 806d0d50 89d6cd98 8a899c88 00010009 nt!KiInterruptDispatch+0x3d (FPO: [0,2] TrapFrame @ 80549020) 04 805490a4 bac3d183 00000046 8a84c028 882e97c8 hal!HalpPmTimerStallExecProc +0x60 (FPO: [1,5,0]) 05 805490c4 b8cb8b50 bafde064 882e981c b8cb8ad6 usbehci!EHCI_RH_PortResetComplete +0x61 (FPO: [2,2,4]) 06 805490e4 804ff550 882e97f8 4d547961 33b06716 USBPORT!USBPORT_AsyncTimerDpc +0x7a (FPO: [4,1,4]) 07 80549200 804ff667 80551f80 80551d20 ffdff000 nt!KiTimerListExpire+0x122 (FPO: [0,62,0]) 08 8054922c 8054111d 80552380 00000000 007af63f nt!KiTimerExpiration+0xaf (FPO: [4,6,0]) 09 80549250 80541096 00000000 0000000e 00000000 nt!KiRetireDpcList+0x46 (FPO: [0,0,0]) 0a 80549254 00000000 0000000e 00000000 00000000 nt!KiIdleLoop+0x26 (FPO: [0,0,0])
?06栈?font color=#ff1493 face="Courier New">USBPORT!USBPORT_AsyncTimerDpc函数来看Q当前CPU果真在勤恳的清理DPCd?/p>
#04栈中的HalpPmTimerStallExecProc 函数是所谓的忙等待(Busy WaitQ函敎ͼ它会(x)让CPU在此循环一定时_(d)q通常是不得以而ؓ(f)之的做法Q因用这L(fng)函数?x)让CPU白白I{。从#05栈的函数名来看Q这个函数是负责理USB 2.0讑֤的EHCI的Root Hub用来重置USB端口的,通常的做法是写某个硬件寄存器Q然后读取同一个或者不同的寄存器,{待g的确认。这U等待通常旉很短。但是从本例的情冉|看,可能出意外了(jin)Q等?jin)很久,很可能是反复读,然后{待Q在反复{的q程中,pȝ收到?jin)强制蓝屏的热键?/p>
分析到这里,我们知道q次pȝ挂死是与USB驱动E序讄的DPCd有关的。这个DPCd在与g通信来重|端口时Q遇C(jin)意外Q于是进入怪圈Q不断@环,锲而不舍,孜孜不倦,没完没了(jin)......【呵呵,汉语的词汇就是丰富?/p>
那么q个DPCd到底遇到什么意外了(jin)? 要想l箋(hu)q究p看代码了(jin)Q源代码不公开Q就考验看汇~的能力?jin)。好在伟大的x86汇编有着强的表辑֊Q很Ҏ(gu)理解Q下一文章中我们l分析。^_^
BTW. 对于DPCQ理解的再深M不过分,有空时可以反复读一下Mark Russinovich的介l:(x)
http://technet.microsoft.com/en-us/sysinternals/bb963898.aspx
]]>
պAVëƬƷþþ |
þþƷɧ |
99þѹƷ |
þѹۿƵ |
þþƷ9988 |
þ99Ʒ |
ҹƷþ |
ƷŮþþ |
þþþþùƷ |
þþþĻɫ |
Avþ |
ɫۺϾþ |
Ʒþþþþþþþ |
þùƷþþ |
ŷպľþ |
˾þô߽ۺ5g |
ݺþþþþۺ |
ŷ þ |
996þùƷ߹ۿ |
þƷAV |
Ʒһþ |
þһ |
þvwww
|
ξþ99ƷþþþþС˵ |
aaþʦ2021Ʒ |
Ʒþۺ
|
þþþþҹƷ |
þþþþþƷ |
þþƷĻ |
پþþƷþ |
һۺϾþ |
99þþƷһѿ |
þ99һ |
99reþþƷҳ2020 |
ŮþþƷ㽶69 |
þɫĻþþ |
ɫۺϾþþþ |
þþƷav鶹ɫ |
þþþһƷɫ
|
˹ھƷþþþӰԺVR |
þþƷֻоƷ2020 |