* updated by Kii Ali, 12-11-2001 ftp://ftp.nsysu.edu.tw/cpatch/faq/tech/tech_inf98.txt Subject: INF 檔大解密 ------------------------------------------------------------------------------------------ .INF 檔大解密 By Issac Chang 1999/02/02 目錄 ------------------------------------------------------------------------ 前言 .INF 檔是甚麼 .INF 檔的功能 .INF 檔的格式 + [Version] 節區 + [Manufacturer] 節區 + [Manufacturer Name] 節區 + [Install] 節區 + [ClassInstall] 節區 + [Strings] 節區 .INF 檔範例一 .INF 檔範例二 .INF 檔執行方式 參考資料 註一 我的資料 ☉前言∼ 回目錄 在中文化 INF-TOOL 的時後,發現微軟的 .INF 檔蠻有趣的,翻了翻相關資料後,願 與大家分享一下小小的心得。 ☉.INF 檔是甚麼∼ 回目錄 .INF是 Device Information File 的縮寫,是微軟為供硬體製造商散佈其設備驅動程 式而發展的—君不見許多硬體的驅動程式是使用 .INF 來安裝的。.INF 檔從 Windows 3.X 時代就開始大量被使用了。   .INF 檔是一種具有特定格式的純文字檔,我們可說它是種安裝腳本檔(Setup Script)。雖然本文所提內容乃出自 Windows 98 Resource Kit,但並不表示依照本 文所撰寫出來的 .INF 檔只適用於 Windows 98。 既然 .INF 只是純文字檔,為甚麼當我們在檔案總管對 .INF 檔按右鍵後,快顯功能 表會出現「安裝」指令呢?這是因為微軟已在其作業系統 Windows 中提供了 Setup API(註一),程式設計師只需用任何文書編輯軟體撰寫 .INF 檔,便可完成大部份的 安裝工作。尤其是在軟體的大小並不是很大的情況下,使用 .INF 檔來進行安裝工作 將會是一個好選擇。本文的目的就是介紹 .INF 檔的功能、結構、並提供了幾個 .INF 範例檔供參考。 ☉.INF 檔的功能∼ 回目錄 您可以使用 .INF檔來: + 複製檔案、刪除檔案、或為檔案重新命名。 + 新增或刪除登錄資料庫(Registry)中的項目。 + 修改重要系統檔(如 Autoexec.bat、Config.sys、.INI 等) ☉.INF 檔的格式∼ 回目錄 如果您曾經撰寫過 DOS 的多重開機檔(Multi-Configuration),您一定很快就能熟 悉 .INF 檔的格式,因為 .INF 檔是由許多節區(Section)組成,在這些節區中定義 的項目可以完成硬體的偵測與軟體(驅動程式)的安裝。.INF 檔案格式如下所示: [Version] 節區 包含對此 .INF 檔的簡短描述與此 .INF 檔支援的設備類型資訊。 [Manufacturer] 與 [Manufacturer Name] 節區 可能列著此 .INF 檔可辨識的所有硬體設備,並可能列出了開發該硬體的廠 商名稱。 [Install] 節區 描述設備驅動程式與硬體設備的實際屬性。它也定義了所有 [Install] 節 區的名稱,在此定義的節區中包含了安裝該設備的資訊與指令。 [ClassInstall] 節區 為設備定義一個新的類別(Class)。此節區是選用的。 [Strings] 節區 此節區中定義了所有可翻譯的字串。如果特定的字串會在 .INF 檔中頻繁地 出現,那麼在此節區為它們定義一個字串變數將會是個好選擇。 . . ... 上述每一個節區通常都會包含一個或多個項目。每個項目是由一個鍵(Key)與一個值 (Value)組成,而鍵與值之間用半形等號(=)連接。例如: Key=Value ; 半形分號後面的文字會被視為註解 當然您也可以在 .INF 檔中加入註解。在一個 .INF 檔中,所有跟隨在半形分號(;) 後的文字都會被視為註解。註解並不一定要在新行開始,您可以在一行文字後面加入 註解。 ☉[Version]節區∼ 回目錄 語法 [Version] Signature="$Chicago$" LayoutFile=filename.inf [Version] 是標準的 INF 檔標頭(必要節區?)。 Signature Signature 字串是不分大小寫的(如:$Chicago$ 與 $CHICAGO$ 會被視為相同,且 For Windows 9X 的 .INF 檔好像一定要寫 $Chicago$)。 filename.inf filename.inf 是用以安裝此驅動程式軟體的 Layout 資訊(來源磁片與檔案)的 .INF 檔檔名。一般來說,Windows 98 的元件其 Layout 檔是 Layout.inf、 Layout1.inf、或 Layout2.inf。此行是選用的,如果您並未指定此行,您必須在 .INF 檔中另外指定 [SourceDisksNames] 與 [SourceDisksFiles] 節區。 下面的範例展示了一個合法的 [Version] 節區: [Version] Signature="$Chicago$" LayoutFile=LAYOUT.INF ☉[Manufacturer]節區∼ 回目錄 語法 [Manufacturer] manufacturer-name | %strings-key%=manufacturer-name-section [Manufacturer] 節區中指出了設備的製造商並指定了 [Manufacturer Name] 節區, [Manufacturer Name] 節區包含了關於此設備驅動程式的額外資訊。 manufacturer-name 製造商名稱。此名稱可由任何可列印字元組成,但必須是唯一的(不得與其他製造商 名稱相同),而且必須以半形引號(" ")括起來。 strings-key 此字串變數必須已在 [Strings] 節區中被定義,本文稍後會提到 [Strings] 節區。 在 .INF 檔中引用的字串變數必須以半形百分比符號(%)括起來。 manufacturer-name-section [Manufacturer Name] 節區名稱。此名稱可由任何可列印字元組成,但必須是唯一的 (不得與其他製造商節區名稱相同)。 下面的範例展示了一個合法的 [Manufacturer] 節區,該節區中使用了一個字串變數 %M1% 來表示製造商名稱。在此範例中,[Manufacturer Name] 節區是APEXD。 [Manufacturer] %M1%=APEXD ; %M1% 變數需已於 [String] 節區定義 ☉[Manufacturer Name]節區∼ 回目錄 語法 [manufacturer-name] device-description=install-section-name, device-id[,compatible-device-id]... [Manufacturer Name] 節區含有有對要安裝的設備的描述,並為要安裝的設備指出 [ Install] 節區。manufacturer-name 節區名稱必須已在 [Manufacturer] 節區中被定 義。 device-description 對要安裝的設備的描述。您可以在此項目使用任何可列印字元或字串變數(當然字串 變數必須在稍後會提到的 [Strings] 節區中定義)。 install-section-name 此設備的 [Install] 節區名稱。 device-id 此設備的辨識指標(Identifier)。 compatible-device-id 相容的設備辨識指標。您可以賦予多個相容的設備辨識指標,但每一個相容的設備辨 識指標必須以半形逗號(,)隔開。 下列範例展示了一個合法的 [Manufacturer Name] 節區。此設備的 [Install] 節區 名稱是 SuperSCSI、設備辨識指標是 *PNPA000、而其相容的設備辨識指標是 *PnPA001。 [APEXD] %DevDesc1% = SuperSCSI, *PNPA000, *PnPA001 對於每個使用此 .INF 檔安裝的驅動程式,安裝程式會使用 [Manufacturer Name] 節 區中的資訊來產生驅動程式描述(Driver Description)、製造廠商名稱 (Manufacturer Name)、設備辨識指標(DeviceID)、與相容的設備清單資訊,並將 這些資訊寫入系統登錄資料庫(Registry)。 ☉[Install] 節區∼ 回目錄 語法 [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] 節區定義了安裝程式與硬體偵測流程需要的資源,以便為新的硬體安裝驅 動程式或軟體。install-section-name 必須已在 [Manufacturer Name] 節區中被定 義,且您僅能使用可列印字元來做為節區名稱。 在此節區中並非每個項目都是必要的。但若您指定了一個項目,您就必須為該項目賦 予一個節區名稱(除了 CopyFiles 項目外)。您可以為每個項目賦予一個以上的節區 名稱,但每個節區名稱之間必須以半形逗號(,)隔開。[Install] 節區中的每個項目 都有其特定格式與意義,稍後我們會談到。每個 [Install] 節區都應包含驅動程式集 的建立日期(?)。 下面的範例展示了一個合法的 [Install] 節區: [MyApplication] Copyfiles=MyAppWinFiles, MyAppSysFiles, @SRSutil.exe AddReg=MyAppRegEntries 如果您將上例的 [MyApplication] 節區更名為 [DefaultInstall],當使用者在檔案 總管中對此 .INF 檔按右鍵,並選擇「安裝」指令時,此 Install 節區將會被執行。 [CopyFiles] 節區 在 CopyFiles 項目中,您除了可以指定節區名稱(該節區中列著要複製的檔案)外, 也可以直接指定一個檔名,但此檔名必須使用一個特殊的表示法,也就是您必須在每 個檔名之前加上一個半形 @ 符號。使用此表示法的每個檔案都會被複製到 [DestinationDirs] 節區中的 DefaultDestDir 項目指定的地方。 下面的範例展示了複製個別檔案與使用檔案節區複製檔案的方法: [MyInstallSection] CopyFiles=FileSection1,@myfile.txt,@anotherfile.txt,LastSectionName [FileSection1] File1.ext File2.ext [LastSectionName] LastFile.ext   [Logical Configuration] 節區 語法 [log-config-section-name] ConfigPriority = priority-value MemConfig = mem-range-list I/OConfig = io-range-list IRQConfig = irq-list DMAConfig = dma-list [Logical Configuration] 節區定義了硬體設備的組態設定,例如中斷要求(IRQ)、 記憶體範圍(Memory Range)、輸入/輸出埠(I/O Port)、與直接記憶體存取通道 (DMA Channel)。一個 .INF 檔中可以包含一個以上的 [Logical Configuration] 節區。log-config-section-name 必須已在 [Install] 節區的 LogConfig 項目中被 定義。 此節區中並非每個項目都是必要的,然而,一旦您使用了一個項目,您就必須賦予對 應的節區名稱。 每個項目可以指定一個以上的資源(IRQ、Memory Range、I/O Port、DMA 等)。然 而,安裝過程中只有項目中的一個資源會被使用。如果一個硬體設備需要 N 個相同類 型的資源,您就必須撰寫 N 個項目。例如,若要讓一個硬體設備使用兩個 IRQ,您必 須使用兩個 IRQConfig 項目。若該硬體設備並不需要 IRQ,您就不須為其設定 IRQConfig 項目。安裝程式會為每一個項目設定二進位邏輯組態記錄,並將這些記錄 新增到登錄資料庫(Registry)中的驅動程式節區。 [Update AutoExec] 節區 語法 [update-autoexec-section] CmdDelete=command-name CmdAdd=command-name[,command-parameters] UnSet=env-var-name PreFixPath=ldid[,ldid] RemOldPath=ldid[,ldid] TmpDir=ldid[,subdir] [Update AutoExec] 節區可以讓您隨心所欲地操縱 Autoexec.bat 檔的內容。 update-autoexec-section 名稱必須已在 [Install] 節區中的 UpdateAutoBat 項目 指定。 在此節區中,並非每個項目都是必要的。如果需要的話,您可以建立數個 CmdAdd、 CmdDelete、與 UnSet 項目;但是 PreFixPath、RemOldPath、與 TmpDir 等項目則各 僅能有一個。 安裝程式會先處理完所有的 CmdDelete 後,才處理 CmdAdd。 若欲取得更多有關 LDID 值的資訊,請參閱本文稍後將提及的 "[Update INI] 節區" 部分。 [Update ConfigSys] 節區 語法 [update-config-section] Buffers=legal-dos-buffer-value DelKey=key DevRename=current-dev-name,new-dev-name DevDelete=device-driver-name DevAddDev=driver-name,configkeyword[,flag][,param-string] Files=legal-dos-files-value PrefixPath=ldid[,ldid]... RemKey=key Stacks=dos-stacks-value [Update ConfigSys] 節區可以讓您新增、刪除、或修改 Config.sys 檔的內容。 update-config-section 名稱必須必須已在 [Install] 節區中的 UpdateCfgSys 項目 指定。 在此節區中並不是每個項目都是必要的。如果需要的話,您可以建立數個 DevRename 、DevDelete、與 DevAddDev 項目,但其他項目則各僅能有一個存在。安裝程式會先 處理所有的 DevRenames、接著處理所有的 DevDelete 項目、最後才處理所有的 DevAddDev 項目。 並不是每個項目都是必要的。如果需要的話,您可以在 Update Config.sys 節區中建 立數個 DevRename、DevDelete、DevAddDev、DelKey、與 RemKey 項目,但是 Buffers、Files、與 Stacks 等項目則各僅能有一個存在。安裝程式遇到此節區時, 會先處理所有的 DevRenames 項目、接著處理所有的 DevDelete 項目,最後才處理所 有的 DevAddDev 項目。 Buffers 項目 Buffers=legal-dos-buffer-value 設定檔案緩衝區的數值。如果您在此項目設定的值比 Config.sys 檔中的 Buffers 值 還低,安裝程式並不會改變 Config.sys 檔中的 Buffers 值。 DelKey 項目 DelKey=Key key 就是在 Config.sys 檔中您想將它變成註解的指令。 DelKey=key 會使得安裝程式將 Config.sys 中的特定鍵(Key)註解起來(亦即在該 行前面加上 REM)。例如 DelKey=Break 會使得 Config.sys 中的 Break=On 該行前 面被加上註解(REM)。DelKey 項目與 RemKey 項目的功能是一樣的。在此節區中您 也可以建立一個以上的 DelKey 和/或 RemKey 項目。 DevAddDev 項目 DevAddDev=driver-name,configkeyword[,flag][,param-string] 新增一行 Device 或 Install 指令到 Config.sys 檔。 driver-name 要新增的驅動程式(.sys)或執行檔(.exe)名稱。 configkeyword 指令名稱。可以是 Device 或 Install。 flag 選用的旗標。設定為 0 表示要將該指令放在 Config.sys 檔的尾端。設定為 1 表示 要將該行指令放在 Config.sys 檔的最頂端。預設值是 0。 param-string 額外的指令參數,假設您用 .INF 為 Config.sys 加入了 Device=Himem.sys,您可能 會想再為該行指令新增一個 /TestMem:On 的參數。 DevDelete 項目 DevDelete=device-driver-name 刪除任何包含指定的驅動程式名稱的行。 device-driver-name 檔案或驅動程式名稱。 下面的範例展示了如何利用 DevDelete 刪除 Config.sys 中包含指定的檔案或驅動程 式名稱的一行或數行: DevDelete=Foo.sys ; CONFIG.SYS 檔中含有的下列數行均會被刪除 Device=Foo.sys ;; 第一行 Install=foo.exe ;; 第二行 Device=Foo.sys /d:b800 /I:3 ;; 第三行 DevRename 項目 DevRename=current-dev-name,new-dev-name 變更 Config.sys 檔中的驅動程式名稱。 current-dev-name 要更改的驅動程式或執行檔名稱。安裝程式會尋找 Config.sys 檔中 Device= 或 Install= 右方的驅動程式或執行檔名稱以便更改之。 new-dev-name 要賦予驅動程式或執行檔的新名稱。 Files 項目 Files=legal-dos-files-value 指定系統一次可存取的檔案數目。若您在 Files 項目的設定值小於 Config.sys 中的 設定,安裝程式將會忽略此 Files 項目。 legal-dos-files-value 指定可開啟的檔案數目(需介於 8 - 255 之間)。 PrefixPath 項目 PrefixPath=ldid[,ldid]... 將 LDID 所代表的目錄加到 Path 項目裡。 ldid 可以是一些預設的 LDID 值或是您在 .INF 檔中設定的新值。若瞭解預設的 LDID 值 代表的目錄,請參閱稍後將提及的 DestinationDirs 節區部分。 RemKey 項目 RemKey=key key 就是在 Config.sys 檔中您想將它變成註解的指令。 RemKey=key 會使得安裝程式將 Config.sys 中的特定鍵(Key)註解起來(REM)。例 如 RemKey=Break 會使得 Config.sys 中的 Break=On 的前頭被加上註解(REM)。 RemKey 項目與 DelKey 項目的功能是一樣的。在此節區中您也可以建立一個以上的 RemKey 和/或DelKey 項目。 Stacks 項目 Stacks=dos-stacks-values legal-dos-stacks-value 合法的 MS-DOS 堆疊設定值。 Stack=a, b a 必須介於 8 - 64 之間的數字。 b 必須是 0 或者是介於 32 - 512 之間的數字。 設定堆疊的數目與大小。若您在 Stacks 項目的設定值小於 Config.sys 中的設定, 安裝程式將會忽略此 Stacks 項目。如果 Config.sys 檔中的設定是 Stacks=9,218, 而 .INF 中設定 Stacks=5,256,安裝程式會將 Config.sys 中的值改成 Stacks=9,256。 [Update INI] 節區 語法 [update-ini-section-name] ini-file, ini-section, [old-ini-entry], [new-ini-entry], [flags] 取代、新增、刪除 .INI 檔中的項目。update-ini-sectionname 必須已在 [Install] 節區的 UpdateInis 項目中被定義。 ini-file 要更改其內項目的 INI 檔名稱。 ini-section 該 INI 檔中要更改的項目的節區名稱。 old-ini-entry 舊的 INI 項目,通常格式是 Key=Value。此參數是選用的。 new-ini-entry 新的 INI 項目,通常格式是 Key=Value。此參數是選用的。不管是鍵(key)或是值 (value)都可使用字串變數替代。例如,您可以使用 %String1% 來代表新字串(或 舊字串),但 %String1% 必須已在 [Strings] 節區被定義。 flags 選用的旗標。 選用的旗標(flags)所代表的意義如下: 旗標值 意義 這是預設值。若 old-ini-entry 的鍵(key)已存在於 .INI 檔中,則該項 0 目會被 new-ini-entry 取代。您必須注意,只要 old-ini-entry 項目的鍵 (key)符合就可以了,old-ini-entry 項目的值(value)並不是重點。 若 old-ini-entry 的鍵(key)與值(value)存均在於 .INI 檔中,則 old-ini-entry 會被 new-ini-entry 取代。注意,只有當 old-ini-entry 1 完全與 .INI 檔中的項目符合的時候,取代動作才會發生。(再提醒您一 次,使用旗標 0 表示只要 old-ini-entry 的鍵(key)與 .INI 檔中的項目 符合,取代動作就會發生)。 若 old-ini-entry 的鍵(key)不存在於 .INI 檔中,則 .INI並不會被變 更。若 old-ini-entry 的鍵(key)存在於 .INI 檔中而且 new-ini-entry 的鍵(key)亦存在於 .INI 檔中,則 .INI 檔中符合 new-ini-entry 的鍵 (key)的項目會被刪除而且 .INI 檔中符合 old-ini-entry 參數的項目會 2 以下列方式處理:.INI 檔中的鍵(key)會被 new-ini-entry 項目的鍵 (key)取代。若 old-ini-entry 的鍵(key)存在於 .INI 檔中而且 new-ini-entry 的鍵(key)不存在於 .INI 檔中,則在 .INI 檔中該項目的 鍵(key)會被 new-ini-entry 的鍵(key)取代,而該項目的值(value) 不會被改變。請注意,.INI 檔中的項目只要與 old-ini-entry 的鍵(key) 符合就可以了,並非鍵(key)與值(value)都必須符合才能使變更發生。 與旗標值設定為 2 時的結果相同,但是 .INI 檔中項目的鍵(key)與值 3 (value)都必須與 old-ini-entry 的鍵(key)與值(value)符合,變更 才會發生。 下面是 System.ini 中的一個節區,其中,drivers 是節區名稱。在 wave=mmdrv.dll 這個項目中,wave 是鍵(key);而 mmdrv.dll 是值(value)。 [drivers] wave=mmdrv.dll ; 鍵(key)=值(value) 如果要將 new-ini-entry 新增到 .INI檔中,您僅需把 old-ini-entry 設定為 NULL。若要刪除 .INI檔中的 old-ini-entry,您僅需把 new-ini-entry 設定為 NULL。您可以使用萬用字元(*)來指定鍵(Key)與值(Value)。 ini-file name 可以是一個字串或者是一個字串變數。字串變數的形式是 %strkey%, 而此字串變數必須已在 [Strings] 節區中被定義。不管您使用的是字串變數或者字 串,它們都必須是合法的檔名。 所謂合法的檔名就是必須包含 .INI檔所在目錄名稱,但您必須使用邏輯目錄辨識指標 (Logical Directory Identifier,LDID)而不可以使用真實的目錄名稱(例如, C:\MyWin98\)。關於 LDID所代表的實際目錄,請參閱本文稍候將會提到的 [DestinationDirs] 節區部分。 LDID 的格式為 %ldid%,其中 ldid 可以是 Setup API 預設的或者是使用者自行於 [DestinationDirs] 節區所定義的目錄。LDID_BOOT 與 LDID_BOOTHOST 已經包含反斜 線,所以 %30%Boot.ini 就代表開機磁碟機根目錄下的 Boot.ini 檔。 下列範例展示了此節區的項目: %11%\Sample.ini, Section1,, Value1=2 ; 上行會在 Sample.ini 檔的 Section1 節區新增一個 Value=2 項目 %11%\Sample.ini, Section2, Value3=*, ; 上行會刪除 Sample.ini 的 Section2 節區中的 Value=3 項目 %11%\Sample.ini, Section4, Value5=1, Value5=4 ; 上行會將 Sample.ini 的 Section4 節區中的 Value5=1 取代為 Value5=4 [Update IniFields] 節區 語法 [update-inifields-section] ini-file, ini-section, profile-name, [old-field], [new-field] 取代、新增、與刪除 .INI 檔中的項目的值(value)的部分。不像 [Update INI] 節 區,[Update IniFields] 可用來取代、新增或刪除一個 .INI 項目的值(value)的 一部份,而不是刪除整個值(value)。update-inifields-section 名稱必須已在 [ Install] 節區中的 UpdateIniFields 項目中被定義。 Any previous comments in the line are removed because they might not be applicable after changes. When looking in the INI file for fields in the line, spaces, tabs, and commas are used as field delimiters. However, a space is used as the separator when the new field is appended to the line. [Add Registry] 節區 語法 [add-registry-section] reg-root-string, [subkey], [value-name], [Flag], [value] 新增子鍵(Subkey)或值(Value)到登錄資料庫(Registry),也可以設定值 (Value)的內容。add-registry-section 名稱必須已在 [Install] 節區的一個 AddReg 項目中被定義。 ☆☆☆☆☆   [Delete Registry] 節區 語法 [del-registry-section] reg-root-string, subkey, [value-name] 從登錄資料庫中刪除子鍵(Subkey)或值(Value)的名稱。del-registry-section 名稱必須已在 [Install] 節區的的一個 DelReg項目中被定義。此節區可以包含一個 以上的項目。每一個項目的功能可能是從登錄資料庫中刪除一個子鍵(Subkey)或值 (Value)的名稱。 [Ini to Registry] 節區 語法 [ini-to-registry-section] ini-file, ini-section, [ini-key], reg-root-string, subkey, flags 將 .INI 檔中的行或節區移到登錄資料庫中、在登錄資料庫的特定鍵(key)下建立或 取代一個項目。ini-to-registry-section 名稱必須已在 [Install] 節區的一個 Ini2Reg 項目中被定義。 [DestinationDirs] 節區 語法 [DestinationDirs] file-list-section=ldid[,subdir ] DefaultDestDir=ldid[,subdir ] [DestinationDirs] 節區定義了特定的 [File-List] 節區中指定的檔案將被複製到的 目的目錄,與任何 [File-List] 節區中未指明目的目錄的預設目的目錄。 file-list section [File-List] 節區的名稱。此名稱必須已在 [Install] 節區的一個 Copyfiles、 RenFiles 或 DelFiles 項目中被定義。 Ldid 關於 Ldid 的名稱、值、與其代表的目錄,請參考下表: LDID 名稱 值 代表的目錄 LDID_SRCPATH 1 安裝程式所使用的暫存路徑,此路徑通常只 在正常的安裝階段中有效。 Temporary setup directory for install LDID_SETUPTEMP 2 path to uninstall location, this is where we backup files that will be overwritten. LDID_UNINSTALL 3 Uninstall (backup) directory path for the copy engine. BUGBUG: backup directory for the copy engine, not used temporary setup LDID_BACKUP 4 directory used by setup, this is only valid during regular install and is guaranteed to be a read/write location for scratch space. LDID_SETUPSCRATCH 5 Temporary setup directory for scratch space. ★ LDID_WIN 10 \Windows 目錄 LDID_SYS 11 \Windows\System 目錄 LDID_IOS 12 \Windows\System\Iosubsys 目錄 LDID_CMD 13 \Windows\Command 目錄 LDID_CPL 14 \Windows\System(控制台元件 .CPL 目錄) LDID_PRINT 15 \Windows Printer 目錄(?) LDID_MAIL 16 \Mail 目錄(?) LDID_INF 17 \Windows\INF 目錄 LDID_HELP 18 \Windows\Help 目錄 LDID_FONTS 20 \Windows\Fonts 目錄 LDID_VIEWERS 21 \Windows\System\Viewers 目錄 LDID_VMM32 22 \Windows\System\VMM32 目錄 LDID_COLOR 23 \Windows\System\Color 目錄 LDID_APPS 24 Applications folder location. Shared directories for net install. ★ LDID_WINBOOT 26 Guaranteed boot device for windows. LDID_MACHINE 27 Machine specific files. LDID_HOST_WINBOOT 28 Boot and old \Windows and DOS directories. LDID_BOOT 30 開機磁碟機的根目錄 LDID_BOOT_HOST 31 Root directory of boot drive host. LDID_OLD_WINBOOT 32 Subdirectory off of Root (optional). LDID_OLD_WIN 33 Old \Windows 目錄(若有的話) LDID_OLD_DOS 34 Old \DOS 目錄(若有的話) LDID_OLD_NET 35 Old network root directory, only valid during network GenUpgrade. Path to MOUSE env. variable if set or LDID_MOUSE 36 same as LDID_WIN only valid after mouse class installer. ★ 變數型 LDID 變數型 LDIDs(VarLDIDs)可確保 .INF 檔能找到現行的 Program Files、 Accessories 等目錄所在位置。 擁有長檔名的目錄或是包含進階字元集的目錄可能會擁有多重 LDIDs。例如,28700 與 28701 均指到 "Program Files",但是 28700 代表短檔名目錄—"Progra~1";而 28701 代表長檔名目錄—"Program Files"。同樣地,28700 與 28702 均指到短檔名 "Progra~1" 目錄,但是 28700 使用 OEM 字集的方式;而 28702 是使用 ANSI字集的 方式來表示。不同的 LDIDs 各有不同的用途。一般說來,OEM/SFN LDIDs 通常被用來 複製檔案;ANSI/LFN 被用來作為那些將寫入登錄資料庫的字串;而 ANSI/SFN 則被使 用來撰寫負責建立程式集捷徑的 Setup.ini 項目。 VarLDID.LFN 與 VarLDID.SFN 節區後的旗標指出了目錄代表的隱含意義。旗標值有下 列意義: 0 = OEM/SFN (預設) 1 = ANSI/SFN 2 = OEM/LFN 3 = ANSI/LFN subdir 子目錄名稱,此目錄之親代目錄是 LDID 所代表的目錄。例如 10,Temp 代表 Windows\Temp 目錄。注意,ldid 與 subdir 之間必須以半形逗點(,)連接,而不是 反斜線(\),且其間不可包含空白(?)。 DefaultDestDir 這個選用的項目會為任何 Copyfile 項目中使用直接複製表示法 (@filename)、或任何未在 [DestinationDirs] 節區中指到的 [File-List] 節區提 供了一個預設的目錄。若 DefaultDestDir 未給定,預設的目錄將會是 LDID_WIN。 下例中,MoveMiniPort 節區的預設目錄是 \Windows\System\Iosubsys,而其他檔案 節區的預設目錄則是開機磁碟機根目錄下的 \BIN 目錄。 [DestinationDirs] MoveMiniPort=12 ; MoveMiniPort 節區的預設目錄是 \Windows\System\IoSubSys DefaultDestDirs=30,bin ; 直接複製到 BootDriveLetter:\Bin [File-List] 節區 [File-List] 節區列出了將被複製、更名、或刪除的檔案名稱。此節區中的項目有三 種格式,至於是哪種格式乃視 [File-List] 節區在 [Install] 節區中是被定義為何 種類型而定。另外,file-list-section 名稱必須已在 CopyFiles 項目中被定義。   將供 CopyFiles 項目使用的 [File-List] 節區有著下列格式: [file-list] destination-file-name,[source-file-name],[temporary-file-name] destination-file-name 目的檔檔名。若為給定來源檔,這也就是來源檔檔名。 source-file-name 來源檔檔名。此項目只有在當來源檔與目的檔檔名不同的時候才需使用。 temporary-file-name 複製過程的暫存檔名稱。Setup API 會先複製來源檔,並賦予它一個暫存檔名。下一 次您重新啟動 Windows 的時候,暫存檔名便會被自動更名為目的檔檔名。如果您要複 製的檔案目前正被 Windows 使用中,您可能需要使用此方法。 下列範例會複製三個檔案: [CopyTheseFilesSec] file11.ext ; 複製 file11.ext file21.ext,file22.ext,file23.ext ;複製 file22.ext,暫時將它更名為 file23.ext file31.ext,file32.ext ;將 file32.ext 複製為 file31.ext   將供 RenFiles 項目所使用的 [File-List] 節區有著下列格式: [file-list-section] new-file-name,old-file-name file-list-section 名稱必須已在 RenFiles 項目中被定義。 下列範例會將 FILE42、FILE52、與 FILE62 分別更名為 FILE41、FILE51、與 FILE61: [RenameOldFilesSec] file41,file42 file51,file52 file61,file62   將供 DelFiles 項目所使用的 [File-List] 節區有著下列格式: [file-list-section] filename file-list-section 名稱必須已在 DelFiles 項目中被定義。 下列範例會刪除三個檔案: [DeleteOldFilesSec] file1 file2 file3 在上例中,乃假設給定的檔案名稱已在 [SourceDisksFiles] 節區中被定義,而且出 現在此節區的邏輯磁片編號(Logical Disk Number)也已在 [SourceDisksNames] 節 區中被定義。 [SourceDisksFiles] 節區 語法 [SourceDisksFiles] filename=disk-number 本節區設定了安裝期間使用的來源檔名稱,與辨識該磁片是否包含這些檔案的指標 (Identifies)。來源磁片的 disk-number 這個 ordinal 必須已在 [SourceDiskNames] 節區中被定義。 下面範例展示了一個合法的 [sourceDisksFiles] 節區,其 disk ordinal 是 1: [SourceDisksFiles] SRS01.386 = 1 [SourceDisksNames] 節區 語法 SourceDisksNames]disk-ordinal="disk-description",disk-label,disk-serial-number 用以安裝特定設備的驅動程式的磁片辨識指標。 下列範例展示了一個合法的 [SourceDisksNames] 節區: [SourceDisksNames] 1 = %ID1%, Instd1, 0000-0000 ☉[ClassInstall] 節區∼ 回目錄 語法 [ClassInstall] Copyfiles=file-list-section[,file-list-section]... 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]... [ClassInstall] 節區會在系統登錄資料庫的 [Class] 節區安裝一個設備的新類別您 安裝到 Windows 98 的每個設備都會有一個相關的類別(即使其類別是 "UNKNOWN"),而且每個類別均有一個 class installer 與其相關。若 .INF 檔中定 義的設備將被安裝到系統中,而且其類別尚未在登錄資料庫中定義,安裝程式則會處 理此節區在此節區中,並非每個項目都是必要的。 下列範例指定了安裝程式將在登錄資料庫建立的類別(class)項目 (AddReg=SampleClassReg),並在 [SampleClassReg] 指定了一個 [Install] 節區 在此範例中的類別描述(Class description)是必要的,而相對鍵(HKR)則指出類 別節區(class section)。此範例建立了一個名為 Sample 的類別並註冊了類別的描 述、Installer與類別的圖示: [ClassInstall] Addreg=SampleClassReg CopyFiles=@Sample.cpl [SampleClassReg] HKR,,,,%SampleClassDesc% HKR,,Installer,,Sample.cpl HKR,,Icon,HEX,00,00 ☉[Strings] 節區∼ 回目錄 語法 [Strings] strings-key=value [Strings] 節區中定義了一個或多個字串變數。字串變數代表著一串可列印字元的組 合。雖然 [Strings] 節區通常放在 .INF檔的最後面,但您可以在 .INF 檔的任何可 以使用字串的地方置入字串變數。 Setup API 會將字串變數出現的地方填入您在此節區中定義的字串。字串變數使用的 必須以半形百分比符號(%)括起來。[Strings] 節區的使用可以讓軟體國際化 (Localization)更容易,因為您可以將所有可翻譯的字串都使用字串變數替代,一 旦有需要發行其他語言版本時,僅需修改字串變數代表的字串即可。 strings-key 字串變數名稱,由文字、數字組成。 value 欲代表的字串內容,可以是文字、數字、及其他可列印字元。如果您在 .INF 檔中欲 使用的字串變數替代的地方之字串需要用雙引號("")括起來,則字串變數代表的字 串也必須使用雙引號("")括起來。 下列範例展示了一個合法的 [Strings] 節區。 [Strings] MSFT="Microsoft" M1="APEX DRIVERS" DevDesc1=APEX DRIVERS SCSI II Host Adapter ID1="APEX DRIVERS SuperSCSI Installation disk" ☉.INF 檔範例一∼ 回目錄 下例是一家名為 Apex Drivers 公司所使用的一個 .INF 檔範例,此 .INF 檔主要是 用來安裝一塊 SCSI II 介面卡的驅動程式。該介面卡需要的 I/O 埠可以是 180H、 190H、1A0h 或 1B0h。該介面卡需獨享一個 IRQ,IRQ 可由下列 IRQ # 擇其一:4、5 、9、10 或 11。若有指定的話,該介面卡也可以使用一個 DMA 通道。 [Version] Signature="$Chicago$" Provider=%MSFT% HardwareClass=SCSIAdapter   [Manufacturer] %M1%=APEXD ; 此製造商的字串變數 [APEXD] %DevDesc1% = SuperSCSI, *PNPA000, *PnPA001 [SuperSCSI] ; Apex Drivers Model 01 - SuperSCSI+ Log_Config = With_Dma, WithoutDMA Copyfiles=MoveMiniPort, @SRSutil.exe AddReg=MOD1 [With_DMA] ; Primary Logical Configuration ConfigPriority = NORMAL I/OConfig = 4@180-1B3%fff0(3:0:) ; Allocate 4 ports at base 180,190,1A0 or 1B0, device decodes ; 10bits of I/O address and uses no Aliases. IRQConfig = 4,5,9,10,11 ; Allocate Exclusive IRQ 4, 5, 9, 10 or 11 DMAConfig = 0,1,2,3 ; Allocate DMA Channel 0, 1 ,2 or 3 [Without_DMA] ; Secondary Logical Configuration ConfigPriority = SUBOPTIMAL I/OConfig = 4@180-1B3%fff0(3:0:) IRQConfig = 4,5,9,10,11 [MOD1] HKR,,DevLoader,,I/OS HKR,,Miniport,,SRSmini.386 [DestinationDirs] MoveMiniPort=12 ; Destination for MoveMiniPort 節區的目的位置是 Windows\System\IoSubSys DefaultDestDirs=30,bin ; 直接複製到 BootDriveLetter:\bin [SourceDiskSFiles] SRS01.386 = 1 [SourceDisksNames] 1 = %ID1%, Instd1, 0000-0000 [MoveMiniPort] SRS01.386 [Strings] MSFT="Microsoft" M1="APEX DRIVERS" DevDesc1=Apex Drivers SCSI II Host Adapter ID1="Apex Drivers SuperSCSI 安裝磁片"   ☉.INF 檔範例二∼ 回目錄 下例是 Tweak UI 98 的 .INF 檔。 ; Author: Win95 Shell Team [version] signature="$CHICAGO$" SetupClass=BASE [DefaultInstall] CopyFiles = TweakUI.Files.Sys, TweakUI.Files.Inf, TweakUI.Files.Hlp AddReg = TweakUI.Add.Reg Ini2Reg = TweakUI.Add.Ini2Reg [DefaultInstall.ntx86] CopyFiles = TweakUI.Files.Sys, TweakUI.Files.Inf, TweakUI.Files.Hlp AddReg = TweakUI.Add.Reg [DefaultInstall.ntmips] [DefaultInstall.ntalpha] CopyFiles = TweakUI.Files.Sys, TweakUI.Files.Inf, TweakUI.Files.Hlp AddReg = TweakUI.Add.Reg [DefaultInstall.ntppc] [Optional Components] TweakUIInstall [TweakUIInstall] CopyFiles = TweakUI.Files.Sys, TweakUI.Files.Inf, TweakUI.Files.Hlp AddReg = TweakUI.Add.Reg Ini2Reg = TweakUI.Add.Ini2Reg OptionDesc = %TWEAKUI% Tip = %TWEAKTIP% ;Parent = AccessTop InstallType = 10 ;Typical, Custom. IconIndex = 16 ;Windows Logo mini-icon for dialogs Uninstall = DefaultUnInstall [DefaultUnInstall] DelFiles = TweakUI.Files.Sys, TweakUI.Files.Inf, TweakUI.Files.Hlp, TweakUI.Files.AutoGen DelReg = TweakUI.Del.Reg [DestinationDirs] TweakUI.Files.Sys = 11 TweakUI.Files.Inf = 17 TweakUI.Files.Hlp = 18 TweakUI.Files.AutoGen = 18 [SourceDisksNames] 1="Tweak UI","",1 [SourceDisksFiles] TWEAKUI.CPL=1 TWEAKUI.INF=1 TWEAKUI.HLP=1 TWEAKUI.CNT=1 [TweakUI.Files.Sys] TWEAKUI.CPL [TweakUI.Files.Inf] TWEAKUI.INF [TweakUI.Files.Hlp] TWEAKUI.HLP TWEAKUI.CNT [TweakUI.Files.AutoGen] TWEAKUI.GID TWEAKUI.FTS [TweakUI.Add.Reg] HKLM,%UTWEAK%,DisplayName,,"PowerToy - %TWEAKUI% - Uninstall" HKLM,%UTWEAK%,UninstallString,,"%10%\rundll.exe setupx.dll,InstallHinfSection DefaultUninstall 132 %17%\Tweakui.inf" HKLM,%SMWCV%\Run,%TWEAKUI%,,"RUNDLL32.EXE TWEAKUI.CPL,TweakMeUp" HKLM,%SMWCV%\RunOnce\Setup,%UPTWEAK%,,"RUNDLL32.EXE TWEAKUI.CPL,TweakMeUp 0" HKLM,%SMWCV%\RunOnce\Setup,%ITWEAK%,,"WINHLP32.EXE -i Main %18%\TWEAKUI.HLP" ; repair a commonly-damaged part of the registry while we're here HKCR,lnkfile,IsShortcut HKCR,piffile,IsShortcut [TweakUI.Add.Ini2Reg] win.ini,Desktop,Wallpaper,HKLM,%BK%,2 win.ini,Desktop,TileWallpaper,HKLM,%BK%,2 [TweakUI.Del.Reg] HKLM,%UTWEAK% HKLM,%SMWCV%\Run,%TWEAKUI% HKLM,%SMWCV%\RunServices,%TWEAKUI% HKLM,%SMWCV%\Explorer\Shell Icons,29 HKLM,%SMWCV%\Applets\TweakUI HKCU,%SMWCV%\Applets\TweakUI [Strings] TWEAKUI="Tweak UI" UPTWEAK="匯入舊版 Tweak UI 設定值" ITWEAK="Tweak UI 簡介" UTWEAK="Software\Microsoft\Windows\CurrentVersion\Uninstall\TweakUI" SMWCV="Software\Microsoft\Windows\CurrentVersion" BK="Software\Microsoft\Windows\CurrentVersion\Setup" TWEAKTIP="變更不同使用者的介面設定值." ☉.INF 檔執行方式∼ 回目錄 + 直接將 .INF 與相關檔案丟給使用者,要他們在檔案總管對著 .INF 按滑鼠右 鍵,並選擇「安裝」指令。 + 先用 Winzip 將 .INF 檔與相關檔案壓縮成 .ZIP,再用 Winzip Self-Extractor 2.2 Beta(沒試過之前的版本)將 .ZIP 轉成 .EXE,在轉檔過 程中將 .INF 指定為自解檔解壓縮完畢時要執行的指令。 + 使用下列指令:%Windir%\System32\rundll32.exe setupapi,InstallHinfSection DefaultInstall 132 FileName.inf + 網路上也找得到專為 .INF 檔寫的 Setup.exe,您僅需將此 Setup.exe 和 .INF 以及相關檔案放在同一目錄,然後執行 Setup.exe 就可以了。 ☉參考資料∼ 回目錄 + Windows 98 Resource Kit + Win32 SDK for Windows 98 and Windows NT + Windows 98 DDK + Microsoft Knowledge Base ☉註一∼ 回目錄 Windows 9X 的 Setup API 並不能供終端使用者指定安裝目錄(所有檔案的安裝目錄 均在 .INF 中被指定),據聞微軟將在下一版本的 Setup API(Windows 2000 的 .INF 檔會加入一些新功能)提供這樣的功能。 ☉我的資料∼ 回目錄 本文作者:Issac Chang 我的電郵:u2504249@mail2.scu.edu.tw 我的網頁:http://mail2.scu.edu.tw/~u2504249         SETUPX.DLL SetupAPI.dll ADVAPI32.dll ------------------------------------------------------------------------------------------ From: "Jonson" To: "patch-author" Subject: Re: .INF 檔大解密 Date: Fri, 12 Feb 1999 04:21:44 +0800 X-MSMail-Priority: Normal > 剛才去看了一下,講得蠻詳細的,不過大部份都和 Windows 95 Resource Kit 一樣。 這份資料實在值得想學習 .INF 檔格式的朋友去看看,可以說幾乎所有微軟公佈的資料都在這兒了。 以下是看了「.INF 檔大解密」之後的幾個疑問及補充: 一. .INF 檔執行方式 1. 使用 Winzip Self-Extractor 2.2 Beta 可以直接將 .INF 指定為自解檔解壓縮完畢時要執行的指令,之前的版本則不行。 2. %Windir%\System32\rundll32.exe setupapi,InstallHinfSection DefaultInstall 132 FileName.inf 這個指令好像是 NT 的指令吧! 3. Setup.exe 所使用的 .INF 檔大都是有自己的規格和微軟的不同,您可比較一下,若是和微軟的規格一樣又何必使用 Setup.exe,這實在是多 此一舉。 二. 註一( Windows 9X 的 Setup API 並不能供終端使用者指定安裝目錄 ) 其實在 WIN 9X 已經可以做到,就是我所謂的 .INF 檔的新式寫法,您可以看一下我的中文化作品「PowerZip 4.51中文化」及「Registry Search + Replace 2.11 中文版」其安裝方式都是使用 .INF 檔讓使用者自行選擇安裝路徑。 三. 其它( [Install] 節區 ) Renfiles 指令不知您是否有測試過,我的經驗是沒有作用。 其實您公佈的資料實在不能稱作「.INF 檔大解密」,Issac Chang 您先別忙著生氣,先看看我的說法: 您公佈的資料其實都是來自微軟的資料,應該說是「.INF 檔格式基本教學」或「INF 檔 - 微軟公佈的資料」。 照慣例,微軟所公佈的資料都不會是最完整的,當然他必須留下一點秘密( 到 MSDN 再賺一筆? ),真正的秘密( 完整資枓 )往往只能從他們的檔案中 窺得端倪,雖然您提及 Tweak UI 98 的 .INF 檔,但您未對其作解說,若您能對其作剖析或解說,那您的資料或許可稱得上「解密」吧! 倘若您尚不能同意我的說法,那就請您試著解答我以下的問題吧: 1. 您知道 .INF 檔在複製檔案時可以比較檔案版本或不比較版本強迫複製嗎?如何做? 2. 您知道在 AddReg 指令中如何加入「字串」形式的 registry,但您知道如何加入「二進位值」或「DWORD」形態的 registry 資料嗎?如何做? 3. Copyfiles 節區中指定的檔案名稱是否支援長檔名? 說真格的,Issac Chang 我不是要扯您後腿、拆您的台或是與您作對,我只是覺得微軟所提供的資料太不像話了,您也是用 WIN 98 的人了,您可以去 WINDOWS 的 INF 目錄下看看,其中有多少 .INF 檔是照微軟公佈的資料格式寫的呢?這些 98 的 .INF 資料在 WIN 95 出來時就有了,幾乎是一模一 樣呢! -- Jonson