珍発見!Google Earth 約 0.05%の確率でインストーラーが動作しないバグ
Google Earth 7.1 のインストーラー って Google Earth 6.0時代の MSI ファイルを直接扱うものから、MSI.DLL を介して一時ファイルに MSIを書き出してこっそりインストーラを裏で起動する方式になってるんですね…。
ところが、Windows 7でGoogleEarthInstall.exe を起動しようと思ったところ、インストールはダイアログも音もなく失敗し、以下のようなログが・・・
=== Verbose logging started: 2015/05/12 13:42:20 Build type: SHIP UNICODE 5.00.7601.00 Calling process: C:\Users\mofmof\Downloads\GoogleEarthWin.exe === MSI (c) (D8:DC) [13:42:20:750]: Resetting cached policy values MSI (c) (D8:DC) [13:42:20:750]: Machine policy value 'Debug' is 0 MSI (c) (D8:DC) [13:42:20:750]: ******* RunEngine: ******* Product: C:\Users ******* Action: ******* CommandLine: ********** MSI (c) (D8:DC) [13:42:20:753]: Client-side and UI is none or basic: Running entire install on the server. MSI (c) (D8:DC) [13:42:20:753]: Grabbed execution mutex. MSI (c) (D8:DC) [13:42:20:956]: Cloaking enabled. MSI (c) (D8:DC) [13:42:20:956]: Attempting to enable all disabled privileges before calling Install on Server MSI (c) (D8:DC) [13:42:20:966]: Incrementing counter to disable shutdown. Counter after increment: 0 MSI (s) (BC:5C) [13:42:21:086]: Running installation inside multi-package transaction C:\Users MSI (s) (BC:5C) [13:42:21:086]: Grabbed execution mutex. MSI (s) (BC:B0) [13:42:21:089]: Resetting cached policy values MSI (s) (BC:B0) [13:42:21:089]: Machine policy value 'Debug' is 0 MSI (s) (BC:B0) [13:42:21:089]: ******* RunEngine: ******* Product: C:\Users ******* Action: ******* CommandLine: ********** MSI (s) (BC:B0) [13:42:21:089]: Note: 1: 2203 2: C:\Users 3: -2147287035 MSI (s) (BC:B0) [13:42:21:090]: MainEngineThread is returning 1619 MSI (s) (BC:5C) [13:42:21:102]: User policy value 'DisableRollback' is 0 MSI (s) (BC:5C) [13:42:21:102]: Machine policy value 'DisableRollback' is 0 MSI (s) (BC:5C) [13:42:21:102]: Incrementing counter to disable shutdown. Counter after increment: 0 MSI (s) (BC:5C) [13:42:21:102]: Note: 1: 1402 2: HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Installer\Rollback\Scripts 3: 2 MSI (s) (BC:5C) [13:42:21:103]: Note: 1: 1402 2: HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Installer\Rollback\Scripts 3: 2 MSI (s) (BC:5C) [13:42:21:103]: Note: 1: 1402 2: HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Installer\InProgress 3: 2 MSI (s) (BC:5C) [13:42:21:103]: Note: 1: 1402 2: HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Installer\InProgress 3: 2 MSI (s) (BC:5C) [13:42:21:103]: Decrementing counter to disable shutdown. If counter >= 0, shutdown will be denied. Counter after decrement: -1 MSI (s) (BC:5C) [13:42:21:103]: Restoring environment variables MSI (c) (D8:DC) [13:42:21:105]: Decrementing counter to disable shutdown. If counter >= 0, shutdown will be denied. Counter after decrement: -1 MSI (c) (D8:DC) [13:42:21:106]: MainEngineThread is returning 1619 === Verbose logging stopped: 2015/05/12 13:42:21 === |
なんか、明らかに表示されているフォルダ(ファイル)名がおかしいようです
実際のコードを見てみましょう
L00404C0C: mov ebx,esi L00404C0E: lea eax,[ebp-20h] push eax call SUB_L00404A77 cmp dword ptr [eax+14h],00000008h pop ecx jc L00404C20 mov eax,[eax] L00404C20: push ebx push edi push L00412608 push eax call [KERNEL32.dll!GetTempFileNameW] push edi push 00000001h lea ecx,[ebp-20h] mov ebx,eax call SUB_L00401356 push edi push ebx mov ecx,esi call SUB_L0040366E mov ecx,[ebp-04h] pop edi mov eax,esi pop esi xor ecx,ebp pop ebx call SUB_L00406ABB leave retn |
少しわかりやすくしてみます
L00404C20: int result = GetTempFileNameW(tmpDir , L"GE", 0, tmpFileName); call SUB_L00401356 ((ebp-20h), 1, 0 ); SetLength (tmpFileName, result, 0 ); |
さて、ここで GetTempFileName 関数の返り値を見てみましょう
戻り値 関数が成功すると、一時ファイルの名前を作成するために使われた一意の数数が返ります。uUnique パラメータが 0 ではない場合、uUnique パラメータと同じ値が返ります。 関数が失敗すると、0 が返ります。拡張エラー情報を取得するには、 関数を使います。 |
どういうことかというと、一時ファイルの名前が GE1111.tmp だった場合は 0x1111、 GE4.tmp だった場合は 0x4 が返るのですが… その返り値で返ってきた文字列をまるめこんでしまってるのです
Windows 7の場合はこの一時ファイルの名前 37+ ユーザー名の長さですから、これ以下に丸め込まれてしまうと関数で作成された一時ファイルが見つからなくてエラーになってしまいます。
Win2000やXPは 42+ユーザー名の長さ 以下だとエラーです。
つまり、 約 0.05 %の確率でインストーラーの起動に失敗してエラーになってしまうわけです。
ところが、 Windows 2000で実行した場合だけ事情が違います。
Win2000とXPと7のGetTempFileName の動作の違い
インストールログはこうなりました
******* Product: C ******* Product: C:\Program Files\Google\C MSI (s) (E0:9C) [14:29:31:548]: Note: 1: 2203 2: C:\Program Files\Google\C 3: -2147287038 |
1回目
******* Product: C: ******* Product: C: MSI (s) (E0:04) [14:30:44:188]: Note: 1: 2203 2: C: 3: -2147287035 |
2回目
******* Product: C:\DOCUME~ ******* Product: C:\DOCUME~ MSI (s) (E0:84) [14:31:45:094]: Note: 1: 2203 2: C:\DOCUME~ 3: -2147287038 |
10回目
******* Product: C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\GE29.t ******* Product: C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\GE29.t MSI (s) (E0:3C) [14:33:00:391]: Note: 1: 2203 2: C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\GE29.t 3: -2147287038 |
41回目
******* Product: C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\GE2B.tmp MSI (s) (E0:24) [14:33:54:391]: Original package ==> C:\DOCUME~1\ADMINI~1\LOCALS~1\Temp\GE2B.tmp MSI (s) (E0:24) [14:33:54:391]: Package we're running from ==> C:\WINNT\Installer\70760.msi : MSI (s) (E0:24) [14:34:24:094]: Product: Google Earth -- Installation completed successfully. MSI (s) (E0:24) [14:34:24:094]: Cleaning up uninstalled install packages, if any exist |
43回目インストール成功
|。・ω・)ノ おいおい …。
Comments