本文共 14281 字,大约阅读时间需要 47 分钟。
INF文件格式要求
一个INF文件是以段组织的简单的文本文件。一些段油系统定义(System-Defined)的名称,而另一些段由INF文件的编写者命名。每个段包含特定的条目和命名,这些命名用于引用INF文件其它地方定义的附加段。INF文件的语法规则:1、要求的内容:在特定的INF文件中所要求的必选段和可选段、条目及命令依赖于所要安装的设备组件。端点顺序可以是任意的,大多数的INF文件安装惯用的次序来安排各个段。2、段名:INF文件的每个段从一个括在方括号[]中的段名开始。段名可以由系统定义或INF编写者定义在Windows 2000中,段名的最大长度为255个字符。在Windows 98中,段名不应该超过28个字符。如果INF设计要在两个平台上运行,必须遵守最小的限制。段名、条目和命令不分大小写。在一个INF文件中如果有两个以上的段有相同的名字,系统将把其条目和命令合并成一个段。每个段以另一个新段的开始或文件的结束为结束。3、使用串标记:在INF文件中的许多值,包括INF编写者定义的段名都可以标示成%strkey%形式的标记。每个这样的strkey必须在INF文件的Strings段中定义为一系列显示可见字符组成的值。4、行格式、续行及注释:段中的每个条目或命令以回车或换行符结束。在条目或命令中,“/”可以没用做一个显示的续行符;分好“;”标示后面的内容是注释;可以用都好“,”分隔条目和命令中提供的多个值。INF文件举例下面是一个完整的.inf文件,它是Windows 2000 DDK提供的USB批量阐述驱动程序范例中所附的.inf文件。; Installation inf for the Intel 82930 USB Bulk IO Test Board;; (c) Copyright 1999 Microsoft;[Version]Signature="$CHICAGO$"Class=USBClassGUID={36FC9E60-C465-11CF-8056-444553540000}provider=%MSFT%DriverVer=08/05/1999[SourceDisksNames]1="BulkUsb Installation Disk",,,[SourceDisksFiles]BULKUSB.sys = 1BULKUSB.inf = 1[Manufacturer]%MfgName%=Microsoft[Microsoft]%USB/VID_045E&PID_930A.DeviceDesc%=BULKUSB.Dev, USB/VID_045E&PID_930A;[PreCopySection];HKR,,NoSetupUI,,1[DestinationDirs]BULKUSB.Files.Ext = 10,System32/DriversBULKUSB.Files.Inf = 10,INF[BULKUSB.Dev]CopyFiles=BULKUSB.Files.Ext, BULKUSB.Files.InfAddReg=BULKUSB.AddReg[BULKUSB.Dev.NT]CopyFiles=BULKUSB.Files.Ext, BULKUSB.Files.InfAddReg=BULKUSB.AddReg[BULKUSB.Dev.NT.Services]Addservice = BULKUSB, 0x00000002, BULKUSB.AddService[BULKUSB.AddService]DisplayName = %BULKUSB.SvcDesc%ServiceType = 1 ; SERVICE_KERNEL_DRIVERStartType = 3 ; SERVICE_DEMAND_STARTErrorControl = 1 ; SERVICE_ERROR_NORMALServiceBinary = %10%/System32/Drivers/BULKUSB.sysLoadOrderGroup = Base[BULKUSB.AddReg]HKR,,DevLoader,,*ntkernHKR,,NTMPDriver,,BULKUSB.sysHKLM,"System/Currentcontrolset/Services/BulkUsb/Parameters","MaximumTransferSize",0x10001,4096HKLM,"System/Currentcontrolset/Services/BulkUsb/Parameters","DebugLevel",0x10001,2[BULKUSB.Files.Ext]BULKUSB.sys[BULKUSB.Files.Inf]BulkUsb.Inf;---------------------------------------------------------------;[Strings]MSFT="Microsoft"MfgName="Intel"USB/VID_045E&PID_930A.DeviceDesc="BulkUsb.Sys Intel 82930 USB Bulk IO Test Board"BULKUSB.SvcDesc="BulkUsb.Sys i82930 Bulk IO test driver"INF文件详解从上面完整的例子来看,可以对INF文件有的一个总体的印象,包括INF文件中包括的段,以及各段的书写格式。下面详细介绍组成INF文件的各个段。1、[Version]段习惯上,每个INF文件都开始于一个Version段,这段确定文件中描述的设备类型,上述范例中的Verson段有如下几条语句:Signature=”$CHICAGO$”Class=USBClassGUID={36FC9E60-C465-11CF-8056-444553540000}provider=%MSFT%DriverVer=08/05/1999Signature指定使用此INF文件的操作系统,可以是$Chicago$、$Windows NT$(含有一个空格)、$Windows 95$(含有一个空格)之一,定界符$必不可少,且这些串是不分大小写的。如果Signature的值不是这些有效的串之一,该INF文件就被人为无效。如果一个INF文件用来向Windows 2000和Windows 98两个平台上安装设备驱动程序,它必须通过DDInstall段来增加系统定义的扩展指定任意操作系统特有的安装信息,而不管Signature是何值。Class指定设备的类名,此范例中指定的是USB类。ClassGuid指定设备注册表的GUID,GUID是一个128位的标识符,DDK头文件DEVGUID.h定义了标准设备类的GUID。Provide标志该INF文件的提供者。%MSFT%的具体内容将在Strings段中定义,范例中的定义是MSFT=”Microsoft”,表明该INF文件的提供者是Microsoft。DriverVer条目提供整个INF文件的版本信息,在每个Install段中加上DriverVer条目,为驱动程序提供版本信息。Install段的驱动程序版本条目更具有专用性,并且比Version段的全局DriverVer条目日期具有更高的优先级。当操作系统搜索驱动程序时,他会选择一个具有更近的DriverVer日期的驱动程序代替一个较早的驱动程序。如果一个INF没有DriverVer条目,操作系统将会用缺省的日期00/00/0000。2、[SourceDiskNames]段该段制定并且命名一个或多个包含源文件的磁盘,这些源文件用于文件拷贝或者重命名操作。该段可以有任意条目,每个条目对应一个源盘。条目格式如下:disk=%strkey%|”disk-description”,[tagfile],[unused],[path]diskid是标志一个源盘的非负整数。这个值可以是十六进制或者十进制的形式标示,但他不能占用多余4个字节的存储单元。等式右边规定一个%strkey%标记或者一个引号引起来的串,描述由diskid所标示盘符的内容或目的。在安装过程中安装程序可以给终端用户显示这个串值。TagFile是一个可选的值,规定一个所带磁盘上提供的特征文件名,不规定任何目录和子目录。安装程序使用特征文件核对用户插入正确的安装盘。特征文件只能用于可移动的介质。Unused值不用在Windows 2000中,只用在Windows 9x中。Path也是个可选项,用于标识磁盘上包含源文件的目录路径。范例中SourceDisksNames段的内容如下:[SourceDiskNames]1=”BulkUsb Installation Disk”…范例规定源盘为磁盘1,在安装期间,安装程序可以给终端用户显示字符串“BulkUsbInstallation Disk”。3、[SourceDisksFiles]段该段命名安装过程中所用的源文件,标志包含这些源文件的磁盘(或者CD-ROM),并提供在所带磁盘上包含的每个文件的目录路径。一个SourcesDisksFiles段可以有任意多条目,磁盘上每个文件都有一个条目。它所包含的条目格式为filename=disked[,[subdir][,size]]。Filename规定磁盘上源文件的名称;diskid对顶一个整数来标志包含源文件的磁盘,即在SourceDisksNames段中规定的diskid;subdir是个可选值,它规定了源磁盘上的文件所在的子目录,如果该条目省略,指定的源文件或者在给定磁盘的根目录中,或者在由SourceDisksNames段中的path条目所指定的目录;size也是个可选值,规定了给定文件的非压缩长度,其以字节标示。范例中SourceDisksFiles段的内容如下:[SourceDisksFiles]BULKUSB.sys=1BULKUSB.inf=1范例中为两个文件建立的条目,这两个文件都在磁盘1中,并且在根目录下。4、[Manufacturer]段该段标志一个或者多个用INF文件安装的设备的制造商,它也为制造商的设备即驱动程序的安装定义Models段名。每个INF文件都必须有Manufacturer段。上述范例的Manufacturer段有一个条目:[Manufacturer]%MfgName%=Microsoft在Strings段中可以找到%MfgName%定义的字符串,本范例中定义的是MfgName=”Intel”,表明设备制造商是Intel。而右边Microsoft也是制造商的Models段的段名。在INF中,为每个制造商的Models段规定了一个INF编写者定义的名字,这个名称要在Manufacturer段中加以应用。范例中的制造商Models段如下:[Microsoft]%USB/VID_045E&PID_930A.DeviceDesc%=BULKUSB.Dev, USB/VID_045E&PID_930A该段属于制造商的Models段,段名是由INF编写者自行定义的,不属于系统段名。每个制造商的Models段至少标识一个设备,并规定设备的厂商ID(VID)和产品ID(PID)同时引用这个设备INF文件的Install段。该段也可以规定一个或者多个附加设备ID,因为有多个与初始硬件ID所识别的设备兼容,同时由相同的驱动程序驱动。当设备管理器发现从检测设备所得到的ID,符号此段定义的ID时,设备管理器就知道找到了正确的INF文件。范例中规定了一个设备,设备的VID是0x045E,而PID是0x930A。VID是由USB管理委员会给每个USB芯片厂商统一分配的,例如Philips公司的VID是0x0471,Cypres公司的VID是0x0547等,范例中的VID是Intel公司的。产品ID(PID)是由各个厂商自己定义的,这里VID0x930A是Intel的一个USB批量传输的实验板。范例中该条目等式右边的BULKUSBDev给设备标识了一个INF文件编写者定义的Install段。5、[DestinationDirs]段该段为所有的硬件拷贝、删除和改名操作规定目标目录。范例中的DestinationDirs段如下:[DestinatinDirs]BULKUSB.Files.Ext=10,System32/DriversBULKUSB.Files.Inf=10.INFDestinationDirs段中条目等式的左边规定INF文件编写者定义的段名,这些段中的文件将会被存入等式右边指定的目录中,并且这些文件可以被INF文件中其他地方的CopyFiles、RenFiles和DelFiles命令引用。例如,范例中这两个段的定义如下:[BULKUSB.Files.Ext]BULKUSB.sys[BULKUSB.Files.Inf]BULKUSB.InfDestinationDirs段中条目等号右边的10是一个逻辑磁盘标志符号(Logical Disk Identifier, LDID),它规定了对文件操作的目标目录标识符,后面跟随的是子目录,作为文件操作的目标地址。范例中第一个文件BULKUSB.sys的目标地址是WinNT/System32/Drivers;第二个文件BULKUSB.Inf的目标地址是WinNT/INF。DestinationDirs段也可以包含一个缺省目标目录DefaultDestDird的条目,为所有对文件的拷贝、删除和更名操作规定省略的目标路径,这些文件没有明确的列在其它条目所引用的文件列表中。Windows DDK的Device Information File Reference文件有其他的LDID熟知的定义,如下表。常用LDID定义LDID数值目标目录00NULL LDID,此LDID可以用来创建新的LDID最后附上我自己对INF的一个理解:
[cpp] view plain copy
; ; test.inf ;整个配置文件安装成功后会在注册表生成一个实例子健 具体位置为:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum;--------- Version Section ---------------------------------------------------
[Version]
;可以是$Chicage$、$Windows NT$(含有一个空格)、$Windows 95$(含有一个空格)之一,定界符$必不可少,且这些串是不分大小写的。
;如果Signature的值不是这些有效的串之一,该INF文件就被认为无效 Signature="$WINDOWS NT$";INF文件的提供者
Provider=drsn_Device;INF文件的版本信息,时间和版本不变的情况下,修改了SYS文件,重新安装INF文件是看不到SYS变化的
;因为系统已经存根了此版本的INF和SYS,它会直接加载已有的文件,调试SYS特别要主要这个问题 ;如果使用VS2012编译,它会自动帮你填写这里,比较省心 DriverVer=08/31/2013,8.33.48.258;如果设备是一个标准类别,使用标准类的名称和GUID 否则创建一个自定义的类别名称,并自定义它的GUID
;自定义的类别在注册表中 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\ 有显示 Class=drsnDevice ClassGuid={BDC0EAC4-AC4B-46af-82EA-C4958B686515};--------- SourceDiskNames and SourceDiskFiles Section -----------------------
;这里两项的设置效果是 加载INF当前目录下的SYS文件
[SourceDisksNames] 1 = %DiskName%,,,[SourceDisksFiles]
Name_Files_Driver = 1,,;--------- ClassInstall/ClassInstall32 Section -------------------------------
;如果不是标准类别设备,这里的配置必须的
[ClassInstall32] Addreg=Class_AddReg;对应的注册表是 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\
[Class_AddReg] HKR,,,,%DeviceClassName% HKR,,Icon,,"-5";--------- DestinationDirs Section -------------------------------------------
;把文件呢复制到相应的目录下,在win2000及其以后系统,12表示%windir%/system32/drivers
;win98中12表示%windir%/system/IoSubsys 所以为了兼容大家都写成10,System32\Drivers [DestinationDirs] Name_Files_Driver = 12;--------- Manufacturer and Models Sections ----------------------------------
;这里是设置模型相关的选项,注意这里VS默认生成的标准设备的配置 如:%ManufacturerName%=Standard,NT$ARCH$
;如果不是标准类别设备这里必须修改,要不然最后加载的时候会出现259错误 [Manufacturer] %ManufacturerName%=Mfg0;这里是模型节的节名,和硬件ID 这个ID可以自定义
[Mfg0] %DeviceDesc%=SysInstall, PCI\VEN_8888&DEV_8888;---------- DDInstall Sections -----------------------------------------------
;这里需要注意WIN2000及其以上的系统这里有个.NT,如果是98这里是[SysInstall],必须要正确设置
[SysInstall.NT] CopyFiles=Name_Files_Driver AddReg=Install_NT_AddReg;这里的drsnWDM是注册表中的服务名 具体地址是 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services
[SysInstall.NT.Services] Addservice = drsnWDM, 0x00000002, Sys_AddService;服务的具体选项
[Sys_AddService] DisplayName = %SvcDesc% ServiceType = 1 ; SERVICE_KERNEL_DRIVER StartType = 3 ; SERVICE_DEMAND_START ErrorControl = 1 ; SERVICE_ERROR_NORMAL;这个地方虽然和[Name_Files_Driver]相同但是不能引用,所以只能照实来写
ServiceBinary = %12%\test.sys[Install_NT_AddReg]
HKLM, "System\CurrentControlSet\Services\drsnWDM\Parameters",\ "BreakOnEntry", 0x00010001, 0; --------- Files (common) -------------
;sys文件名 便于配置文件其它地方使用
[Name_Files_Driver] test.sys;--------- Strings Section ---------------------------------------------------
;字符串设置 便于配置文件其它地方使用
[Strings] ProviderName="drsn" ManufacturerName="drsn soft" DiskName="test Source Disk" DeviceDesc="test protect" SvcDesc="drsn" DeviceClassName="drsn_Device"以上INF是对32位驱动的支持,如果要同时支持32位和64位 兼容INF如下:
[cpp] view plain copy
; ; Ring0.inf ;整个配置文件安装成功后会在注册表生成一个实例子健 具体位置为:HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum;--------- Version Section ---------------------------------------------------
[Version]
;可以是$Chicago$、$Windows NT$(含有一个空格)、$Windows 95$(含有一个空格)之一,定界符$必不可少,且这些串是不分大小写的。
;如果Signature的值不是这些有效的串之一,该INF文件就被认为无效 Signature="$Windows NT$";INF文件的提供者
Provider=drsn_Device;INF文件的版本信息,时间和版本不变的情况下,修改了SYS文件,重新安装INF文件是看不到SYS变化的
;因为系统已经存根了此版本的INF和SYS,它会直接加载已有的文件,调试SYS特别要主要这个问题 ;如果使用VS2012编译,它会自动帮你填写这里,比较省心 DriverVer=;如果设备是一个标准类别,使用标准类的名称和GUID 否则创建一个自定义的类别名称,并自定义它的GUID
;自定义的类别在注册表中 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\ 有显示 Class=drsnDevice ClassGuid={BDC0EAC4-AC4B-46af-82EA-C4958B686515};--------- ClassInstall/ClassInstall32 Section -------------------------------
;如果不是标准类别设备,这里的配置必须的
[ClassInstall32] Addreg=Class_AddReg;对应的注册表是 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\
[Class_AddReg] HKR,,,,%DeviceClassName% HKR,,Icon,,"-5";--------- SourceDiskNames and SourceDiskFiles Section -----------------------
;这里两项的设置效果是 加载INF当前目录下的SYS文件
[SourceDisksNames] 1 = %DiskName%,,[SourceDisksFiles]
Name_Driver_File = 1,, Name_Driver_File64 = 1,,;--------- DestinationDirs Section -------------------------------------------
;把文件呢复制到相应的目录下,在win2000及其以后系统,12表示%windir%/system32/drivers
;win98中12表示%windir%/system/IoSubsys 所以为了兼容大家都写成10,System32\Drivers ;由于INF同时支持32位,64位所以这里要写上2中情况 [DestinationDirs] Name_Driver_File = 12 Name_Driver_File64 = 12;--------- Manufacturer and Models Sections ----------------------------------
;这里是设置模型相关的选项,注意这里VS默认生成的标准设备的配置 如:%ManufacturerName%=Standard,NT$ARCH$
;如果不是标准类别设备这里必须修改,要不然最后加载的时候会出现259错误 ;NT表示32位,NTAMD64表示64位 [Manufacturer] %ManufacturerName%=Device,NT,NTAMD64;这里是模型节的节名,和硬件ID 这个ID可以自定义
[Device.NT] %DeviceDesc%=SysInstall, PCI\VEN_8888&DEV_8888[Device.NTAMD64]
%DeviceDesc%=SysInstall, PCI\VEN_8888&DEV_8888;---------- DDInstall Sections -----------------------------------------------
;这里需要注意WIN2000及其以上的系统这里有个.NT,如果是98这里是[SysInstall],必须要正确设置
[SysInstall.NT] CopyFiles=Name_Driver_File AddReg=Install_NT_AddReg;这里的drsnWDM是注册表中的服务名 具体地址是 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\
[SysInstall.NT.Services] Addservice = drsnWDM, 0x00000002, Sys_AddService;服务的具体选项
[Sys_AddService] DisplayName = %SvcDesc% ServiceType = 1 ; SERVICE_KERNEL_DRIVER StartType = 3 ; SERVICE_DEMAND_START ErrorControl = 1 ; SERVICE_ERROR_NORMAL;这个地方虽然和[Name_Driver_File]相同但是不能引用,所以只能照实来写
ServiceBinary = %12%\test.sys[Install_NT_AddReg]
HKLM, "System\CurrentControlSet\Services\drsnWDM\Parameters",\ "BreakOnEntry", 0x00010001, 0;---------------------64位支持---------------
[SysInstall.NTAMD64] CopyFiles=Name_Driver_File64 AddReg=Install_NT_AddReg64[SysInstall.NTAMD64.Services]
Addservice = drsnWDM, 0x00000002, Sys_AddService64[Sys_AddService64]
DisplayName = %SvcDesc% ServiceType = 1 ; SERVICE_KERNEL_DRIVER StartType = 3 ; SERVICE_DEMAND_START ErrorControl = 1 ; SERVICE_ERROR_NORMAL ServiceBinary = %12%\test64.sys[Install_NT_AddReg64]
HKLM, "System\CurrentControlSet\Services\drsnWDM\Parameters",\ "BreakOnEntry", 0x00010001, 0; --------- Files (common) -------------
;sys文件名 便于配置文件其它地方使用
[Name_Driver_File] test.sys[Name_Driver_File64]
test64.sys;--------- Strings Section ---------------------------------------------------
;字符串设置 便于配置文件其它地方使用
[Strings] ProviderName="drsn" ManufacturerName="drsn soft" DiskName="drsn WDM Device Source Disk" DeviceDesc="drsn WDM Device" SvcDesc="drsn" DeviceClassName="drsn_Device" 起初对兼容性的INF有个疑问:是WDM驱动安装程序自己判断32位或64位进行安装吗?还是把2个设备从配置文件读出来系统来判断呢?为此做了一个实验,把%ManufacturerName%=Device,NT,NTAMD64分解为 Device.NT 和 Device.NTAMD64(注意这里是点号不是逗号) 操作系统会加载2个设备配置,所以根据当前系统位数来选择安装一个合适的设备,结果印证了结论1是正确的。
对此WDM驱动安装程序也需要修改,有起初的直接读取%ManufacturerName%=Mfg0去寻找[Mfg0]块,改变为分析是否是兼容的INF,如果不是按照前边的来,如果是进行分解具体代码如下:
[cpp] view plain copy
//兼容INF时 比如szKey为%ManufacturerName%=Device,NT,NTAMD64 分解为Device,NT 或 Device,NTAMD64 根据系统类型把 szKey设置为相应的配置 从而把兼容性INF //变成了单一化的INF, 如果是单一模式的INF 如果32位INF 或者 64位INF时 比如szKey为%ManufacturerName%=Mfg0 函数会直接返回不会进行处理 BOOL IsSupport64Inf(PCHAR szKey) { CHAR szTmpStr[3][128]={0};PCHAR pStr=NULL, pSplit = ",", pNextStr = NULL; pStr = strtok_s(szKey, pSplit, &pNextStr); for(int i=0; pStr; i++) { StringCchCopyA(szTmpStr[i], 20, pStr); pStr=strtok_s(NULL, pSplit, &pNextStr); } //如果逗号数量少于2个 说明是32或64位的单一INF文件 if(szTmpStr[2][0]==0) { return FALSE; } StringCchCopyA(szKey, 128, szTmpStr[0]); strcat_s(szKey, 128, ","); //根据系统判断 需要安装的设备 if(IsWow64()) { strcat_s(szKey, 128, szTmpStr[2]); } else { strcat_s(szKey, 128, szTmpStr[1]); } return TRUE;
}
另外还需要注意的是WDM安装程序也要区分32位和64为,因为WDM安装程序会用到SetupDiCallClassInstaller函数API,此函数必须有相应位数的程序来调用,详细可见:1.进入设备管理器 右击带***问号的MTP-属性-详细信息-选择 设备范例 ID 或 硬件 ID
显示为如下信息:USB\VID_XXXX&PID_XXXX 记下VID.PID后面的四位XXXX 2.找到c:\windows\inf\wpdmtp.inf打开 如果找不到,应该是隐藏了。这要到控制版面-文件夹选项-查看-选显示隐藏文件 找到[Generic.NTx86] %GenericMTP.DeviceDesc%=MTP, USB\MS_COMP_MTP %GenericMTP.DeviceDesc%=MTP, USB\VID_xxxx&PID_xxxx&MI_00[Generic.NTamd64] %GenericMTP.DeviceDesc%=MTP, USB\MS_COMP_MTP %GenericMTP.DeviceDesc%=MTP, USB\VID_xxxx&PID_xxxx&MI_00 用刚记下的VID.PID后面的四位XXXX替换上面的XXXX
po主的wpdmtp.inf中只有[Generic.NTx86] %GenericMTP.DeviceDesc%=MTP, USB\MS_COMP_MTP [Generic.NTamd64] %GenericMTP.DeviceDesc%=MTP, USB\MS_COMP_MTP 所以额外添加 %GenericMTP.DeviceDesc%=MTP, USB\VID_xxxx&PID_xxxx&MI_00 即可 3.在设备管理器中点带***问号的MTP驱动,右键-更新驱动,成功检测出,over转自https://blog.csdn.net/whatday/article/details/10608431
转载于:https://blog.51cto.com/baiading/2095245