|
Mac OS 9.0 時代
このセクションでは、Mac OS 9.0 File Manager の FCB
に関連する機能について説明します。また、Mac OS 9.0
で加えられた変更の背後にある合理的な根拠も示します。さらに、オープンファイル数に対する新しい制限が
8,169 になった理由についても説明します。
Design Goals
Mac OS 9.0
には、次のような File Manager
に対する大幅な拡張が組み込まれています。
- 長いファイル名 (255 Unicode 文字)
やサイズの大きなファイル (> 2 GB) などの HFS Plus
の機能にアクセスするための新しいプログラミングインタフェース
- オープンファイル数の制限を 348 から 8169
に拡大する新しい FCB テーブルフォーマット
- 大部分の File Manager
呼び出しをプリエンプティブタスク (MP タスク)
から実行する機能
拡張された File Manager に対する設計条件の 1
つは、これまでにドキュメント化されているプログラミングインタフェースを使用しているソフトウェアを正常に動作させつつ、これらの新しい機能をインプリメントするということでした。オープンファイルの最大数を増加させるためには
FCB
テーブルフォーマットに変更を加える必要がありますが、このフォーマットはデベロッパが依存できるものとしてこれまでドキュメント化されていませんでした。
|
注意:
FCB
テーブルのフォーマットに依存することの危険性はこれまで繰り返し警告されてきました。
- 『Inside Macintosh II』 (127 ページ)「警告:
ファイルコントロールブロックのサイズと構造は
Macintosh
システムソフトウェアの将来のバージョンで変更される可能性があります」
- 『Inside Macintosh IV』 (181 ページ)「警告:
ファイルコントロールブロックのサイズと構造は
Macintosh
システムソフトウェアの将来のバージョンで変更される可能性があります」
- 『Inside Macintosh V』 (386
ページ)「ファイルコントロールブロック
(FCB)、ボリュームコントロールブロック (VCB)
などのシステムデータ構造体をメモリ内で直接的に検査または操作しないでください。File
Manager 呼び出しを使って、FCB および VCB
情報にアクセスします
- 『Inside
Macintosh: Files』, (2-81 ページ)「注意:
ファイルコントロールブロックのサイズと構造は
Macintosh
システムソフトウェアの将来のバージョンで変更される可能性があります。安全のため、File
Manager 関数の PBGetFCBInfo
を呼び出して、オープンファイルに割り当てられている
FCB の情報を取得してください」
- 「Technote 1089, HFS
について (改訂版)」
「次の例は、説明を目的としてあげられているだけです。この例をそのまま使用すると、将来のシステムソフトウェアとの間で互換性の問題が発生する可能性があります」
|
Gestalt
Mac OS 9.0 では、システムが新しい FCB
テーブルフォーマットを使用していることと、FCBSPtr、FSFCBLen、またはそれらのローメモリアクセッサルーチン
(LMGetFSFCBLen を除く) に依存できないことを示す新しい
Gestalt ビットが定義されています。この Gestalt ビットは
gestaltFSAttr の gestaltMustUseFCBAccessors (ビット 13)
です。原則として、FCB
アクセッサを使用すべきかどうかを判断するためにこの Gestalt
ビットを使用しないでください。むしろ、使用可能な場合は、常に
FCB アクセッサを使用するようにしてください。
大きな変更
Mac OS 9.0 では、FCB
情報がプライベートテーブルに格納されるようになりました。ただし、このテーブルのフォーマットはデベロッパ向けにドキュメント化されていません。
これまでパラレル FCB テーブルに格納されていた情報は拡張
FCB の中にまとめられました。拡張 FCB は、FSM.h
ファイルの中で ForkControlBlock
型によって定義されています。
また、Mac OS 9.0 は FCB
テーブル内にイテレータコントロールブロックを格納します。詳細については、「イテレータコントロールブロック」
を参照してください。
FCB への直接アクセスを必要とするデベロッパはFSM
アクセッサを使用する必要があります。また、Mac OS 9.0
にはさらにいくつかの FSM
アクセッサが導入されました。詳細については、「新しい
FSM アクセッサ」 のセクションを参照してください。
68K
コードとローメモリ
FCB
テーブルフォーマットに大量の変更が加えられたことを考えれば、クラシック
FCB テーブルフォーマットに関連するローメモリグローバル
(前述したFCBSPtr と FSFCBLen)
がもはや何の意味も持たないことを明らかです。Apple
ではもともと、これらの変数に、アクセスするとバスエラーを引き起こすような値を設定しようと考えていましたが、さまざまな検討を加えた結果、このようなポリシーに落ちつきました。
残念ながら、Apple が提供する GetVRefNum
のグルーはクラシック FCB
テーブルフォーマットに依存しています。このグルーは多くの 68K
アプリケーションに静的にリンクされているため、Apple
ではクラシック FCB
テーブルを完全に排除できませんでした。むしろ、このグルーが正常に動作し続けるように、フェイク
FCB テーブルが注意深く組み立てられています。
|
注意:
Apple が提供する GetVRefNum
のグルーは、さまざまな開発環境のさまざまなライブラリの中に組み込まれています。
- MPW は「Interface.o」の中に GetVRefNum
を含んでいます。
- CodeWarrior は「MacOS.lib」の中に GetVRefNum
を含んでいます。
- Think C および Symantec C
は「MacTraps」の中に GetVRefNum
を含んでいます。
- Think Pascal は「Interface.Lib」の中に
GetVRefNum を含んでいます。
|
フェイク FCB テーブルはこれまで同様、FCBSPtr
によってポイントされますが、FSFCBLen は 4
に設定されています。テーブルは、システム上に実際に存在する各
FCB に対応した複数のフェイク FCB
から構成されています。フェイク FCB は FSFCBLen (4 バイト)
によって配置され、それぞれは、フェイク FCB 内への 20 ($14)
バイトのオフセット (FSFCBLen によってレポートされる、FCB
の境界を $10 バイト超えた位置) に有効な fcbVPtr
を含んでいます。次の図はこのレイアウトを図式化したものです
このレイアウトにより、GetVRefNum は、すべてフェイク FCB
テーブルを使用して、FCB
テーブルの検索、ファイル参照番号が有効であるかどうかのチェック、および
FCB の fcbVPtr
フィールドの検索を行うことができるようになります。
|
注意:
次に、Interface.o の GetVRefNum
グルーを逆アセンブルした結果を示します。
; function GetVRefNum(fileRefNum: integer; VAR vRefNum: integer): OSErr;
GetVRefNum
MOVEA.L (A7)+,A1 ; リターンアドレスをポップ
MOVEQ #$00,D1 ; fileRefNum を取得 (ゼロ拡張)
MOVE.W $0004(A7),D1 ;
MOVEA.L FCBSPtr,A0 ; FCB テーブルポインタと
MOVE.W FSFCBLen,D0 ; FCB サイズを取得
BMI.S NoHFS ; 負の数なら HFS 以前
@HFS
DIVU.W D0,D1 ; fileRefNum を FSFCBLen で除算
BRA.S DoneDivision
@NoHFS
DIVU.W #$005E,D1 ; fileRefNum を HFS 以前の
; FCB で除算
@DoneDivision
SWAP D1 ; fileRefNum mod FCB サイズを取得
SUBQ.W #$2,D1 ; fileRefNum mod FCB サイズが
BNE.S BadResult ; 2 でなければ、エラーアウト
MOVE.W $0004(A7),D0 ; fileRefNum が FCB テーブルの
CMP.W (A0),D0 ; サイズよりも大きい場合は、
BCC.S @BadResult ; エラーを返す
MOVEA.L $14(A0,D0.W),A0 ; 適切な FCB、VCB へのポイントから
; fcbVPtr を取り出す
MOVE.W $004E(A0),D0 ; VCB から vcbVRefNum を取り出す
MOVEQ #$00,D1 ; noErr
BRA.S @GoodResult
@BadResult
MOVEQ #$00,D0
MOVE.W #$FFCD,D1 ; rfNumErr
@GoodResult
MOVEA.L (A7),A0 ; D0 を vRefNum の中におく
MOVE.W D0,(A0) ;
ADDQ.W #$6,A7 ; パラメータをポップ
MOVE.W D1,(A7) ; D1 を関数の結果の中におく
JMP (A1) ; 呼び出し元に制御を戻す
|
|
|
注意:
フェイク FCB
テーブルは、オープンファイルの数に対する 8169
という制限の根拠になっています。以前と同様に、フェイクテーブルのサイズは
32KB に制限されています。SInt16 をラップするために
FCB
テーブル内を移動するコードが生成される可能性があるため、最後の
94 バイトを超えた位置に FCB
が配置されることはありません。したがって、フェイク
FCB で使用可能な数は、(32768 - 94 - 2) div 4 +
1、つまり 8169 になります。
|
PowerPC
コードとローメモリアクセッサ
PowerPC コードのケースはいくらか単純です。PowerPC
コードの場合、GetVRefNum
のインプリメンテーションはシステムソフトウェアの一部であるため、新しい
FCB テーブルフォーマットに対応するように修正されました。
一方、FCBSPtr および FSFCBLen
に対するローメモリアクセッサルーチンはより興味深い問題を提起しました。これらのルーチンは
FCB
テーブルのフォーマットに依存していないため、デベロッパは理論的にはこれらのルーチンを使用していないはずでした。しかし現実には、驚くほど多くのアプリケーションがこれらのルーチンを使用していることが明らかになり、Apple
ではこれらのルーチンの動作を再検討せざるをえなくなりました。
最終的な決定は次のとおりです。
- LMGetFCBSPtr、LMSetFCBSPtr、および LMSetFSFCBLen
はすべて dsMustUseFCBAccessors (119)
システムエラーを発生させる。
- LMGetFSFCBLen はこれまで同様 FSFCBLen の値 (現在は 4)
を返す。
次に、このような変更の根拠を示します。
- FCB テーブルのフォーマット (FCBSPtr
によってポイントされる)
は根本的に変更されました。このため、このフォーマットに依存するソフトウェアは正常に動作しなくなります。ソフトウェアが正常に動作しなくなるのであれば、ソフトウェアの動作をできるだけ早く停止させるのが得策といえます。これにより、古いソフトウェアによって発生する可能性のあるデータの消失を防ぐことができます。
- 明確なシステムエラー番号を使用することで、テクニカルサポート担当者がこの問題を迅速に診断できるようになります。
- FSFCBLen にはドキュメント化された使用法(前述したように、HFS
が存在するかどうかをテストします)
があるため、この目的で使用する FSFCBLen
は今後も正常に動作し続けます。
イテレータコントロールブロック
Mac OS 9.0 の File Manager
は「イテレータ」と呼ばれる新しいメカニズムを導入し、ディレクトリ内またはボリューム上にあるすべての項目を検出できるようになりました。イテレータは、特定のバルクカタログオペレーションのステータスを保持するために使用される絶対オブジェクトです。FSIterator
データ型によって記述されるイテレータは、FSOpenIterator
によって作成され、FSCloseIterator によって廃棄されます。
トラディショナル Mac OS では、FSIterator のステータスは
FCB テーブル内の
イテレータコントロールブロック (of type
IteratorControlBlock)
の中に保持されます。イテレータコントロールブロックは FCB
に似ていますが、オープンファイルではなく FSIterator
のステータスを保持する点が異なります。
FSM
アクセッサを使用するソフトウェアでは、このようなイテレータコントロールブロックの取り扱いに十分注意する必要があり、これらを
FCB
として単純に取り扱うことだけは絶対に避けなければなりません。FCB
の moreFlags フィールドに含まれる fcbIteratorBit
をテストすることで、IteratorControlBlock と ForkControlBlock
を明確に識別することができます。
|
重要:
FCB の moreFlags フィールドは Mac OS 9.0
より前には存在しません。Gestaltを使って、イテレータコントロールブロックのテストを条件づけてください。
|
新しい FSM アクセッサ
Mac OS 9.0 は、前述したルーチンを補足する多数の新しい
FSM
ユーティリティルーチンを導入しました。次のようなルーチンが導入されました。
- UTGetForkControlBlockSize - FCB
のサイズを返します。LMGetFSFCBLen
はもはや使用できず、システムの進化とともに FCB
もさらに拡張されることが予想されるため、このルーチンが必要です。
- UTResolveFileRefNum - 指定した FCB
に対応するファイル参照番号を返します。
- UTCheckFCB - FCBRecPtr が有効な FCB
をポイントしているかどうかを検証できます。
- UTCheckForkPermissions - UTCheckPermission
に代わるルーチンで、使い方がいくらか簡単になっています。
また、FCB
は検索リストの中に置かれ、オープンファイルの検索が高速化されました。次のルーチンを使用することで、外部ファイルシステムもこのような検索リストによる処理の高速化の恩恵を享受できるようになります。
UTAddFCBToSearchList
UTRemoveFCBFromSearchList
UTLocateFCBInSearchList
このようなルーチンはすべて、今後、「Guide to the File
System
Manager」の改訂版の中でドキュメント化される予定です。
|
注意:
これらの FCB アクセッサルーチンは Carbon
の一部ではありません。Carbon コードには、FCB
への直接アクセスは含まれていません。詳細については、Concrete
Advice「現実に即した提案」
のセクションを参照してください。
|
|