获取已安装 INF 文件的原始源路径

本主题介绍如何检索安装在系统 INF 目录中的 INF 文件的原始源路径。 虽然没有 SetupAPI 函数可以直接执行此检索,但可以通过在 INF 文件中包含条目来间接执行检索,以便可以使用访问 INF 文件条目的 SetupAPI 函数从已安装的 INF 文件中检索原始源路径信息。

此方法仅适用于安装在系统 INF 文件目录中的 INF 文件。 不能对 驱动程序存储中存在的 INF 文件使用此方法。

Windows 驱动程序工具包 (WDK) 中随烤箱示例一起提供的辅助安装程序使用此方法,本主题包含演示此方法的烤箱示例的摘录。 有关烤箱示例的详细信息,请参阅 WDK 的 src\general\toaster 目录中提供的toasterpkg.htm。

若要使用此方法检索已安装 INF 文件的原始源路径,请执行以下操作:

  1. 在 INF 文件中包含一个部分,其中包含其第一个字段为 %1% 字符串密钥标记的条目。 默认情况下,%1% 字符串密钥标记表示 INF 文件的原始源路径。 当 Windows 安装此类 INF 文件时,它会使用已安装的 INF 文件版本保存原始源路径字符串。 请注意,仅当使用 %1% 时,此方法才有效,如此示例中所示。 一般情况下,%1% 解析的内容与上下文相关。 例如, add-registry 节 条目中的 %1% 字段不会解析为原始源路径;相反,此上下文中的 %1% 解析为 驱动程序存储中相应 INF 文件的路径。

  2. 使用 SetupOpenInfFileSetupFindFirstLineSetupGetStringField 从包含 %1% 字符串密钥标记的条目中检索原始源路径。

例如, toasterpkg.inf 包括以下 [ToasterCoInfo] 节,其中包含一个自定义 OriginalInfSourcePath 条目,其第一个字段是 %1% 字符串密钥标记。

[ToastCoInfo]
; Used by the toaster co-installer to figure out where the original media is
; located (so it can start value-added setup programs).
OriginalInfSourcePath = %1%

如果配置 INF 如烤箱示例所示,则可以在系统 INF 目录中安装 INF 文件后检索原始源路径。 若要检索原始源路径,请先调用 SetupOpenInfFile 以打开已安装的 INF 文件。 例如, 来自 toastco.c 的以下代码示例打开已安装的 toasterpkg.inf 文件。

// Since the INF is already in %SystemRoot%\Inf, we need to find out where it
// originally came from.  There is no direct way to ascertain an INF's
// path of origin, but we can indirectly determine it by retrieving a field
// from our INF that uses a string substitution of %1% (DIRID_SRCPATH).
//
hInf = SetupOpenInfFile(DriverInfoDetailData->InfFileName,
                        NULL,
                        INF_STYLE_WIN4,
                        NULL
                        );

打开已安装的 INF 文件后,调用 SetupFindFirstLine 以检索包含其第一个字段为 %1% 字符串密钥标记的条目的部分的第一行。 接下来,调用 SetupGetStringField 以检索此条目的第一个字段并检索 INF 文件的原始源路径。 例如, 来自 toastco.c 的以下代码示例检索包含自定义 OriginalInfSourcePath 条目的行,然后检索该条目的第一个字段。 由于原始 INF 中的第一个字段是 %1% 字符串密钥标记, 因此 SetupGetStringField 将返回 INF 文件的原始源路径。

// Contained within our INF should be a [ToastCoInfo] section with the
// following entry:
//
//     OriginalInfSourcePath = %1%
//
// If we retrieve the value (i.e., field 1) of this line, we'll get the
// full path where the INF originally came from.
//
if(!SetupFindFirstLine(hInf, L"ToastCoInfo", L"OriginalInfSourcePath", &InfContext)) {
   goto clean0;
}
if(!SetupGetStringField(&InfContext, 1, *MediaRootDirectory, MAX_PATH, &PathLength) ||
  (PathLength <= 1)) {
  goto clean0;