NUL をコピーする話

MS-DOSには "NUL" というデバイスがある。ある程度パソコンを使っている人なら 聞いた事があるとおもう。NUL は虚無のデバイスである。メッセージをうるさく 出力するコマンドをバッチファイルの中で使う時に、

C:\>henoheno >NUL

等とやって黙らせたりしますな。所で、

C:\>copy henoheno NUL

なんて言う風にファイルをNULにコピーしたらどうなるかというと何も起こらない。 まあ、もっともな事なのだが・・
では、

C:\>copy NUL henoheno

てな風に、NUL をファイルにコピーするとどうなるか・・・? サイズ0のファイルが残る事もなく henoheno は削除されてしまう・・。

おお、なぜだ? なんだか納得できるような出来ないような現象である。しかし、何に 使えるかなぁ・・del するかわりに copy NUL henoheno とやるのも面倒な だけだし。


で、だ。

windows95 になって、WINDOWS ディレクトリにWININIT.INI というファイルがある(かも知れない) のはご存知ですかぁ? これは何かというと、インストーラプログラムなんかが、ファイルをコピーしようと した時に、コピー先のファイルが既に存在していて、かつ現在使用中で書き込み禁止 状態の場合等、取りあえず違う名前でコピーしておいてWININIT.INIに後で置き換える 様に指示しておくと、次回リブート時にシステムが置き換えてくれるというものなのだ。ちなみ に処理された後は自動的に消滅する

例えばこんな感じ。

------------------
[rename]
C:\heno.dll=C:\heno1.dll
NUL=C:\popo.exe
------------------
※ちなみにここでのファイル名は、ロングファイル名は使えない。ブート時にロングファイル名 を扱うファイルシステムがロードされる前にこの処理が行われるためらしい。ださい・・(;;)。

で、上の例で1行目は、C:\heno.dll を C:\heno1.dll で置き換えろという意味だが、 2行目のような使い方もできる。これはファイル c:\popo.exe を削除しろという意味である。 しかし、だ。ちょっと待てよ・・。順番から言えばこれは、C:\popo.exe を NUL にコピーしろと いう事ではないのか?なぜこれで削除するのだ?? まあ、そういう仕様ならしかたないが。 という事だけですめばよいのだが、このやり方だと困った事がある。削除したいファイルが複数ある時に、

---------------------
[rename]
NUL=C:\test1
NUL=C:\test2
NUL=C:\test3
---------------------
等とやらねばならないのだが、これでは.iniファイルを簡単に扱える WritePrivateProfileString() APIが 使えないのである。複数なくても、自分がWININIT.INIに書き込もうとした時に既に誰かが NUL=??? の行を登録しているかも知れない。 普通の.iniファイルは必ず key=value の組み合わせで、 key が同じものは1つしか存在しないのである。 SDK のドキュメントにも、書き込む時にはWritePrivateProfileStringを使わずにこのファイルをパースしろ と書いてある。そんな面倒な・・・(;;)


で、ここまで話が進んでですな。当然次に思い付くのは・・

C:\test=NUL

は果たしてどう解釈されるのだろうか? という事である。素直に考えれば、NUL がc:\testにコピー されるわけだから、削除されるのではないのか?これなら、削除したいファイルが複数あっても WritePrivateProfileString でOKである。おお、よかったよかった。早速やってみよう・・てな 訳で、Wininit.ini を

---------------------
[rename]
C:\test1=NUL
C:\test2=NUL
C:\test3=NUL
---------------------
という風に作ってリブート! さて・・・どうなるか。と思っていると。

システムファイルのアップデートができませんでした

Windows は起動できないかも知れません

だそうだ・・。なんと恐ろしいメッセージ。

まあ、起動はできたし、結果的にtest1〜test3は削除された事はされたのだが・・ こりゃあきまへんな・・お粗末。


はて、ここでなにか勘違いしている事に気が付いた。 WININIT.INI は [copy] ではなく [rename] セクションなのだな・・。 なるほど、rename か。しかしだ、コマンドラインの rename はリネーム先のファイルが既存であれば エラーして何もしないではないか。WININIT.INI はリネーム先が既存でも有無を言わさず置き換えてしまう のだ。ここら辺が勘違いの元に違いない。そうに違いない。と、言い訳はいいとして。

WININIT.INI については、[rename] セクションに指令を書くという事しか明らかではないのだが、 ほんとにそうなのか?もしかして [copy] セクションというのを作るとコピーしてくれたりなんかして・・。 と甘い期待を抱きつつ、

----------------------
[copy]
C:\test2=C:\test1
----------------------
等とやってみる。おお、いかにもコピーしてくれそうだ、そうに違いない。と、またまたリブート。 今度は何も変なエラーメッセージが出ずに起動する。めでたい。正常に処理されたかのように WINDOWS ディレクトリの WININIT.INI は消えている。で、 test2 はどうなのだ?

とルートディレクトリを調べる・・・が、単に無視されたようだ。

つまらん。