InfVerif 错误 1330 - 1333

InfVerif 错误 1330 有助于防止一个目标文件被多个源文件覆盖的功能性错误。 例如:

[CopyFiles.A]
DesiredFileName1,SourceFile1A ; Used by DDInstallSection A

[CopyFiles.B]
DesiredFileName1,SourceFile1B ; Used by DDInstallSection B

当多个 DDInstall 节使用 CopyFiles 指令将不同的源文件复制到单个目标文件时,如果 DDInstall 节都在同一系统上处理,这些 CopyFiles 可能会发生冲突。 例如,如果两个不同的设备使用相同的驱动程序但安装部分不同,或者在某些脱机驱动程序映像和部署方案中。 由于来自不同 DDInstall 节的多个源文件被复制到同一个完全相同的目标文件中,因此来自不同 DDInstall 节的不同源文件会相互覆盖,因此复制的最后一个文件是放置在目标中的文件,这可能不是预期的结果。

案例

本文档提供了如何将旧语法更新为方法以消除以下情况下的功能性错误的指导。 并非所有情况都在下面列出,因为每个 INF 可能有特定的其他原因。

  • 不同的 DDInstall 节 为一个服务重命名服务二进制文件

  • 不同的 DDInstall 节重命名源文件,以便将其复制到驱动程序或用户模式应用程序访问的目标文件位置

不同的 DDInstall 节 为一个服务重命名服务二进制文件

以下代码是一个示例,说明不同的 DDInstall 节如何为一个服务重命名服务二进制文件:

[DDInstallSection_A]
CopyFiles = CopyFiles.A

[DDInstallSection_B]
CopyFiles = CopyFiles.B

[CopyFiles.A]
ServiceBinaryFile, ServiceBinaryA

[CopyFiles.B]
ServiceBinaryFile, ServiceBinaryB

[DDInstallSection_A.Services]
AddService = ServiceName, 0x00000002, ServiceName_Install

[DDInstallSection_B.Services]
AddService = ServiceName, 0x00000002, ServiceName_Install

[ServiceName_Install]
ServiceType    = 1
StartType      = 3
ErrorControl   = 0
ServiceBinary  = %12%\ServiceBinaryFile

若要更新此代码,请为不同的二进制文件创建不同的服务名称:

[DDInstallSection_A]
CopyFiles = CopyFiles.A

[DDInstallSection_B]
CopyFiles = CopyFiles.B

[CopyFiles.A]
ServiceBinaryA

[CopyFiles.B]
ServiceBinaryB

[DDInstallSection_A.Services]
AddService = ServiceName1, 0x00000002, ServiceName1_Install

[DDInstallSection_B.Services]
AddService = ServiceName2, 0x00000002, ServiceName2_Install

[ServiceName1_Install]
ServiceType    = 1
StartType      = 3
ErrorControl   = 0
ServiceBinary  = %12%\ServiceBinaryA

[ServiceName2_Install]
ServiceType    = 1
StartType      = 3
ErrorControl   = 0
ServiceBinary  = %12%\ServiceBinaryB

不同的 DDInstall 节重命名源文件,以便将其复制到驱动程序或用户模式应用程序访问的目标文件位置

在这种情况下,驱动程序正在访问用作动态文件位置的固定文件位置。 若要有一个动态变量跟踪多个源文件,可以使用 AddReg HKR 条目来存储可在运行时检索的路径。 这很有效,因为 AddReg HKR 条目相对于设备存储。

AddReg HKR 条目指定源文件的文件位置,而不是选择单个目标文件将源文件复制到:

[A.AddReg]
HKR,, FileName1Path, "%13%\SourceFile1A"

[B.AddReg]
HKR,, FileName1Path, "%13%\SourceFile1B"

可以从设备上的设置中检索目标文件的位置,而不是访问固定文件位置。 目标文件位置由 INF 存储在注册表值中,并通过驱动程序中的 API 调用检索。

若要通过 INF 预配值,请使用 INF AddReg 指令,该指令使用 HKR reg-root 条目,该条目位于从 INF DDInstall 节INF DDInstall.HW 节引用的 add-registry-section 中。

由于注册表值会跟踪目标文件而不是单个目标文件位置,因此驱动程序必须以不同的方式访问这些文件。 若要访问目标文件,驱动程序现在需要调用以下 API 之一才能打开注册表值,并让它返回源文件的位置:

WDM

WDF

其他用户模式代码

注意

在本例中,INF 有效负载的文件的目标位置不会影响解决方案。 但是,为了使用最佳做法,该示例使用 DIRID 13,因为它通过更少的文件副本提供了更快的安装。 有关详细信息,请参阅“使用 DIRID”和“从驱动程序存储运行”。

下面的示例代码显示了如何更新使用旧语法的 INF。

映射到一个目标文件的不同源文件的详细信息

源代码 注释
[DestinationDirs] CopyFiles.A = 12 CopyFiles.B = 12
[DDInstallSection_A] CopyFiles = CopyFiles.A
[DDInstallSection_B] CopyFiles = CopyFiles.B

手动选择文件的存放位置
[CopyFiles.A]
DesiredFileName1,SourceFile1A ; HW Version A
DesiredFileName2,SourceFile2A ; HW Version A
[CopyFiles.B] DesiredFileName1,SourceFile1B ; HW Version B DesiredFileName2,SourceFile2B ; HW Version B

文件复制技术:重命名文件,以便正在安装的 DDInstall 节选择将源文件复制到驱动程序链接到的目标文件路径。

如果在安装之前复制了所有 DDInstall 节的所有文件,则此方法不起作用。

使用 AddReg HKR 条目进行更新的详细信息

源代码 注释
[DestinationDirs] CopyFiles.A = 13 CopyFiles.B = 13 

最佳做法是将所有内容都保留在驱动程序存储目录 (Dirid 13) 中
[DDInstallSection_A] CopyFiles = CopyFiles.A
[DDInstallSection_A.HW] AddReg = A.AddReg
[DDInstallSection_B] CopyFiles = CopyFiles.B
[DDInstallSection_B.HW] AddReg = B.AddReg


为每个 DDInstall Section.HW 添加 AddReg 节,以跟踪安装所需的文件。
[A.AddReg] HKR,, FileName1Path, "%13%\SourceFile1A" HKR,, FileName2Path, "%13%\SourceFile2A"
[B.AddReg] HKR,, FileName1Path, "%13%\SourceFile1A" HKR,, FileName2Path, "%13%\SourceFile2A"


多个源文件位置映射到一个注册表值。 这很有效,因为 DDInstall 或 DDInstall.HW 节中的 HKR AddReg 存储在设备设置中。 当设备与此驱动程序包一起安装时,它只会使用其中一个 DDInstall 部分,因此只会使用其中一个 HKR AddReg,并且不会发生冲突。
[CopyFiles.A]
SourceFile1A ; HW Version A
SourceFile2A ; HW Version A
[CopyFiles.B] SourceFile1B ; HW Version B SourceFile2B ; HW Version B

所有文件都映射到自己的位置,因此不会出现功能性错误,并且 INF 将传递 InfVerif。
不要使用 CopyFiles 重命名 DestinationDirs 包含 Dirid 13 的文件。

从驱动程序访问文件位置(伪代码)

Before (Fixed Filename):
    OpenFile(Path\DesiredFileName1)

After (Dynamic Filename):
    OpenDeviceRegistryKey(Device, &KeyHandle)
    RegistryKeyQueryValue(KeyHandle, FileNamePath1, &SourceFile)
    OpenFile(SourceFile)

从用户模式访问文件位置

从用户模式访问目标文件时,将没有驱动程序所具有的设备上下文。 在这种情况下,需要添加一个额外的步骤。 在打开项句柄之前,找到包含指示要加载的文件的注册表值的设备。

请参阅从驱动程序存储运行,了解如何筛选设备列表以查找设备,并在用户模式下打开注册表位置的句柄,使用 Dirid 13 获取最佳做法。

错误 1331-1333

错误 1331 - 1333 都是相同的问题,但分别与注册表值、服务内的注册表值和服务有关。 错误 1330 文档中的示例介绍了解决错误 1331 - 1333 的技术。