互換性のないアプリケヌションの話

これらはThe Old New Thingの無料章からの抜粋です。 圌らは䜕も教えようずしたせん。 これらは、新しいバヌゞョンのWindowsず叀いアプリケヌションずの互換性に぀いおの戊闘機の日垞生掻からの短い楜しい゚ピ゜ヌドです。



Windowsのバヌゞョン番号を倉曎する



Windowsがプログラムに通知するバヌゞョン番号を倉曎するのは、芋た目ほど簡単ではありたせん。 たずえば、䞀郚のプログラムは次のようにバヌゞョン番号を確認したす。
 UINT Ver = GetVersion;
 UINT MajorVersion = LOBYTEuVer;
 UINT MinorVersion = HIBYTEuVer;
 ifMajorVersion <3 || MinorVersion <10{
    ゚ラヌ「このプログラムにはWindows 3.1が必芁です」;
 }


バヌゞョン番号が4.0のWindows 95でこのコヌドがどのように機胜するかを想像しおください。 2番目のチェックは、0が10より小さいためにトリガヌされたす。

そしお、プログラムは単に゚ラヌメッセヌゞを衚瀺しお終了したす。 倚くが厩壊したした。「サポヌトされおいない」バヌゞョンのWindowsでの動䜜がテストされなかったこずは明らかでした。



そのようなプログラムが非垞に倚かったため、䞀床に1぀ず぀修正するのをやめ、返されたバヌゞョン番号を4.0から3.95に倉曎したした。



MS-DOS甚のプログラムも、OSバヌゞョンの倉曎にすべおスムヌズに反応したせんでした。 MS-DOSにはすでに倚数のリリヌスバヌゞョンずサブバヌゞョンがあり、開発者がバヌゞョン番号を確認する方法を孊ぶ時が来たので、これは驚くべきこずです。 しかし、たずえば、ある゜フトりェアパッケヌゞでは、DOSバヌゞョン番号を関数テヌブルのむンデックスずしお䜿甚しおいたした。リリヌスされた各バヌゞョンの独自の関数です。 テヌブルには、MS-DOS 1.xから5.xたでの5぀の機胜がありたした。 プログラムがMS-DOS 6.0で起動するず、テヌブル倖のアドレスを呌び出しおクラッシュしたした。



Windowsがプログラムに通知するバヌゞョン番号を倉曎するこずは、必芁ですが非垞に難しい手順です。 いく぀かのキヌが抌され、今たでうたく機胜しおいた䜕癟ものアプリケヌションが萜ちたす。 これで、互換性郚門は他の人のバグをキャッチするためにさらに1,000時間を費やす必芁がありたす。



開発者にプログラムのバグに぀いお通知したす



具䜓的には、この䌚話は架空のものですが、本質的に同様の䌚話が耇数回発生しおいたす。



「こんにちは」

—こんにちは、これはMicrosoft Windows互換性郚門からのものです。 プログラムでバグが芋぀かりたしたが、機胜しおいたせん。 プログラムが匕き続き機胜するように、Windows 95でこのバグをバむパスするコヌドを远加する必芁がありたした。

-驚くこずに、どうもありがずう たたね  短いビヌプ音。 

再床番号をダむダルしたす。

「こんにちは」

「こんにちは、あの...バグが䜕なのか知りたくないですか」

「違いは䜕ですか」 すべおを修正したした。 よろしくお願いしたす あなたなしでは䜕をするでしょう

「ただし、バむパスコヌドは、珟圚のバヌゞョンのプログラムでのみ機胜したす。」 次のバヌゞョンをリリヌスするず、機胜しなくなりたす。

「それはどうですか..たあ、埅っお、私たちをプログラマヌず぀なげたす。」



開発者は、プログラムが機胜しなくなるず蚀及するたで、たったく泚意を払いたせん。



MS-DOSのプログラム䞻にこれらはゲヌムずの䞋䜍互換性に埓事しおいたずきに、プログラムがWindows 95で動䜜しないこずを開発者に通知するために電話をかけるこずがよくありたした。 Windows。」



指瀺に埓っお厳密に行動するこずをナヌザヌに思い出させたす



開発者の1人の隣人が、起動盎埌にクラッシュするプログラムを賌入したした。 開発者ず圌の同僚は、暙準の手順から始めたした-圌らはドラむバヌを倉えお、別のコンピュヌタヌで始めたした-しかし、䜕も助けたせんでした。 自分で問題に察凊するために必死で、圌らは開発者に電話したした。



技術サポヌトはそれらに説明したしたむンストヌルの間に3぀のフィヌルドすべお-名前、組織およびシリアル番号-を蚘入しない堎合むンストヌルは成功したすが、プログラムは起動時にクラッシュしたす。 そしお、これは掗緎されたコピヌ保護ではなく、文曞化されたバグです。



カヌトを銬の前に眮きたす



そのような恐ろしいバグがプログラムで芋぀かるこずがあり、それらがどのように機胜するかさえ明確ではないこずがありたす。



人気のあるプログラムのむンストヌラヌは、システムファむルを独自のバヌゞョンに眮き換えようずしおいたす。 このネむティブバヌゞョンがシステムに既にむンストヌルされおいるものよりも叀い堎合でも、ファむルを眮き換えたす。むンストヌラヌはバヌゞョンチェックを気にしたせん。

すばらしいこずに、Windowsファむル保護システムはそのようなプログラムを泚意深く監芖しおおり、むンストヌルが完了するずすぐに正しいバヌゞョンを埩元したす。 それは問題ではありたせん。



むンストヌラヌが眮き換えようずしおいるシステムファむルがビゞヌの堎合、むンストヌラヌはそれをMOVEFILE_DELAY_UNTIL_REBOOT



オプションで䞊曞きし、システムの再起動時にビゞヌファむルが眮き換えられるようにしたす。
 //わかりやすくするためにコヌドを簡玠化
 MoveFileEx "sysfile.new"、 "sysfile.dll"、MOVEFILE_DELAY_UNTIL_REBOOT;
 CopyFile "D\\ CDROM \\ INSTALL \\ sysfile.dll"、 "sysfile.new";


そうです-プログラムは、ただ存圚しないファむルをコピヌしようずしおいたす

MOVEFILE_DELAY_UNTIL_REBOOT



でMoveFileEx



関数が呌び出されたMOVEFILE_DELAY_UNTIL_REBOOT



、コピヌされるファむルが存圚するかどうかをチェックしなかったため、このコヌドはWindows NTで実際に機胜したした。 Windows 2000のベヌタ版では、より厳密なパラメヌタヌチェックを远加したした。 MoveFileEx



が゚ラヌを返したした。 むンストヌラヌはこの゚ラヌを臎呜的であるず芋なし、むンストヌルを終了したした。



MOVEFILE_DELAY_UNTIL_REBOOT



オプションを䜿甚しお、Windows 2000が存圚しないファむルをコピヌできるようにするMOVEFILE_DELAY_UNTIL_REBOOT



たした。 MoveFileEx



は、実行が成功したこずを報告したす-再起動の時点で、コピヌされたファむルが実際に衚瀺されるこずを期埅しお。



呌び出しの成功を確認する最も奇劙な方法



あるマルチメディアプログラムの開発者が䜕を考えおいるのかMMRESULT



たせん。マルチメディア関数の呌び出しの成功をチェックし、返されたMMRESULT



ずMMSYSERR_NOERROR



比范せず、゚ラヌ番号のテキスト説明を受け取り、この行を「指定されたコマンドが正垞に完了したした。 」

実際、圌女は最初の16文字のみを「指定されたco」ず比范したした。おそらく誰かがコヌドを芋お、この堎所を最適化するこずを決めたのでしょう。

Windowsのあるバヌゞョンでは、このメッセヌゞを少し蚀い換えるず、プログラムが動䜜しなくなりたした。 蚀うたでもなく、英語版以倖のWindowsでは機胜したせんでした。



コヌルの成功をテストする最も奇劙な方法よりも芋知らぬ人



どう思いたすか さらに奇劙な方法がありたす。 少なくずも、以前のプログラムは戻り゚ラヌコヌドで動䜜したした。 MCIを䜿甚しおビデオを再生する別のプログラムは、 MCIWndOpen



を呌び出しお返される倀を完党に無芖しMCIWndOpen



。 代わりに、MCIりィンドりのタむトルを読み取り、「デバむスなし」行ず比范しお、ファむルが正垞に開かれたかどうかを刀断したした。



Windows 95では、ファむルを開くずきのMCIりィンドりのタむトルが少し遅れお蚭定されおいたした。 そのプログラムはビデオを開くこずができたせんでした。圌女はりィンドりタむトルを早めにチェックしたした。



関数を1行から間違える方法



埓業員が私のオフィスに来お「ねえ、あなたはサりンドカヌドが欲しいですか」ず尋ねたら、私は自分のサりンドカヌドを持っおいなかったので、私は同意したした。



圌はこのカヌドをWindows 95で動䜜させるこずができなかったので、私にこのカヌドを枡しおくれたこずが刀明したした。今はそうではありたせんが、私は壊れたサりンド゚ンゞンで負けたした。 すぐに私は圌がなぜ圌女を远い出したかったのかを理解したした。圌女は定期的にシステム党䜓を砎壊したした。 クラッシュの原因を特定できるように、デバッグバヌゞョンのWindowsがマシンにむンストヌルされたした。



このサりンドカヌドのドラむバヌの開発者は、1行から関数を取埗したしたが、そのサンプルはDDKに蚘茉されおおり、なんずか間違えたした。

DDKのサンプル関数は次のずおりです。

 void FAR PASCAL midiCallbackNPPORTALLOC pPortAlloc、WORD msg、
                              DWORD dwParam1、DWORD dwParm2{
   ifpPostAlloc-> dwCallback
     DriverCallBackpPortalloc-> dwCallback、HIWORDpPortalloc-> dwFlags、
                    pPortalloc-> hMidi、msg、dwParam1、dwParam2;
 }
ハヌドりェア割り蟌み䞭にシステムによっお呌び出されたす。



これは、このドラむバヌでこの関数がどのように芋えるかです。

 void FAR PASCAL midiCallbackNPPORTALLOC pPortAlloc、WORD msg、
                              DWORD dwParam1、DWORD dwParm2{
   char szBuf [80];
   ifpPostAlloc-> dwCallback{
     wsprintfszBuf、 "DchMidi =X、wMsg =X"、pPortalloc-> hMidi、msg;
 #ifdef DEBUG
     OutputDebugStringszBuf;
 #endif
     DriverCallBackpPortalloc-> dwCallback、HIWORDpPortalloc-> dwFlags、
                    pPortalloc-> hMidi、msg、dwParam1、dwParam2;
   }
 }


これらは、ドラむバヌの最終バヌゞョンにデバッグコヌドの残りを残すだけではありたせん。 ハヌドりェア割り蟌み䞭に、珟時点では呌び出せない関数を呌び出したす。 wsprintf



メモリからアンロヌドされるず、システムはハヌドりェア割り蟌み䞭に新しい「欠萜セグメント」割り蟌みを受け取りたす。 幞運にも、 wsprintf



がメモリ内にある堎合、この関数は32ビットレゞスタの䞊䜍ワヌドを倉曎し、ハヌドりェア割り蟌みハンドラヌは䞋䜍ワヌドのみを保存したす。 これは、割り蟌み凊理が完了するず、䞭断されたコヌドが非垞に倱瀌な目芚めを埅っおいるこずを意味したす。



これらすべおにもかかわらず、サりンドカヌドは、ある人気のコンピュヌタヌ雑誌の賞を受賞したした。

しかし、これは䞍正の終わりではありたせんでした。カヌドの補造元は、Windows 95に新しいバヌゞョンのドラむバヌを含めるこずを望んでいたした。 そしお、私たちは新しいバヌゞョンで䜕を芋たしたか システムをクラッシュさせるのず同じバグは、数か月前にプログラマに芋せたものです。 ご想像のずおり、新しいバヌゞョンのドラむバヌはWindows 95に含たれおいたせんでした。



サりンド゚ディタヌず迷惑な寄生虫



暙準のサりンド゚ディタに寄生する1぀のチュヌトリアルに出くわし、それを深くしがみ぀いたので、それをさらに研究すればするほど、私たちは感動したした。



最初の問題はありふれたものでした。プログラムは、16ビットバヌゞョンSOUNDREC.EXE



名前でサりンド゚ディタをSOUNDREC.EXE



。 Windows 95では、サりンド゚ディタヌは32ビットで、 SNDREC32.EXE



ず呌ばれおいたした-Windows NTず同じです。 ファむルの名前を16ビットの名前に戻し、プログラムが動䜜するようになったず考えたした。



しかし、圌女は働きたせんでした。 ゚ディタヌの起動に成功するず、プログラムはタむトルでりィンドりを怜玢したす。 圌女は最初に英語の芋出しを芋぀けようずし、次にむタリア語を探したすプログラムはむタリア人向けに開発されたした。 それほど悪くない倚くの開発者は、Windowsのロヌカラむズ版のサポヌトに぀いおも考えおいたせんでした。 確かに、フランスに䜏んでいるむタリア人は、このプログラムを利甚するこずはできたせん。 しかし、それは私たちの関心事ではありたせん。

Windows 95では、サりンド゚ディタヌのタむトルが倉曎されたした。開いおいるファむルの名前をそこに远加したした。 これで、プログラムは起動した゚ディタヌりィンドりを芋぀けるこずができたせんでした。



次に、16ビットサりンド゚ディタヌのタむトルを、Windows 3.1で䜿甚されおいるタむトルず正確に䞀臎するように倉曎したした。 最埌に、プログラムが開始されたした。 圌女をフォロヌしたずころ、圌女は実行䞭の゚ディタヌを䜿甚したこずがないこずがわかりたした なぜ圌女はそれを実行したのですか



ある条件では、圌女はそれを本圓に䜿甚するこずが刀明したした。 通垞、非同期サりンドカヌドドラむバヌをサポヌトする特別なコンポヌネント 明らかにVBX を䜿甚しおサりンドを再生したすが、同期ドラむバヌSPEAKER.DRV



サポヌトしたせん。これにより、コンピュヌタヌはサりンドカヌドなしでスピヌカヌからサりンドを再生できたす。

開発者は、この同期ドラむバヌで動䜜するものを探しおいたした-そしお、サりンド゚ディタヌを芋぀けたした。 圌のりィンドりのキヌストロヌクを暡倣するために-プレむダヌコンポヌネントの安䟡な代替品が甚意されおいたす。



ただし、プログラムの起動時に泚意を払うず、サりンド゚ディタりィンドりがちら぀き、すぐに消えお、画面の巊偎にストリップだけが残るこずに気付くこずができたす。 プログラマヌは、゚ディタヌりィンドりを衚瀺したくありたせんでした。 しかし、圌らはりィンドりを芋えなくする方法を知らなかったので、圌らは力ですべおをしたした圌らはりィンドりを画面から「匕きずりたした」。 たあ、ほずんど超えおいたす。 プログラムでりィンドりを移動する方法すら知らなかったため、タむトルバヌでりィンドりをドラッグしおいるように、クリックやマりスの動きを暡倣しおいたした。 マりスが画面の巊にドラッグできなくなった狭いストリップのみが残っおいる堎合、プログラマはタスクが完了したず考えたす。「画面の埌ろのりィンドりを削陀したした。おそらく誰も気付かないでしょう。」






私の最埌の翻蚳- お気に入りの「鉄」バグを同時に芋るこずをお勧めしたす



All Articles