高度な検索
Developer Connection
Member Login ログイン | ご入会 ADC連絡先

Technote 1123

Start Manager Extension Table Mechanism


目次

基礎概念

システム機能拡張のロード/実行の監視

システム機能拡張のロード/実行の制御

リファレンス - 機能拡張テーブルマネージャ

まとめ - 機能拡張テーブルマネージャ

タートマネージャは Mac OS 8.1 で改訂され、システム起動時にシステム機能拡張のロードの監視と制御を行う仕組が追加されました。

この TECHNOTE では、スタートマネージャの変更点とプログラムがシステム機能拡張をロードする過程を監視または制御する方法を説明します。


基礎概念

Mac OS 8.1 以前は、システム機能拡張は 3 つのフォルダから順にロード/実行されていました。3 つのフォルダとは、機能拡張フォルダ、コントロールパネルフォルダ、システムフォルダです。各フォルダ内のシステム機能拡張は、ディスクに記録されている順序でロード/実行されていました。HFS ボリューム (Mac OS 標準形式) では、アイテム名は ASCII 文字で保存されるため、アイテムは RelString 順にカタログファイルに保存されます。つまり、RelString 関数を使ってソートされています。ファイルマネージャの GetFInfo ルーチンが RelString の順にファイルを返すのはこのためです。

Mac OS 8.1 が導入されて、新しいブートディスク形式、HFS Plus (Mac OS 拡張形式) が登場しました。HFS Plus ボリュームでは、アイテム名は ASCII 文字ではなく、ユニコード形式で保存されるため、HFS ボリュームとは違う順序でカタログファイルにアイテムが保存されます。HFS Plus ボリュームでのソート順の詳細については、HFS Plus ボリューム形式についてのドキュメントを参照してください。

注意:
アプリケーションは、ファイルがボリューム上で一定の順序に保存されることをあてにしてはいけません。ボリューム形式が違えばアイテムのソート順も違う可能性があり、全くソートされていない場合さえあるからです。


Roman スクリプトシステムを使用しているシステムでは、GetFInfo が返す HFS Plus ボリュームのファイルの順序は RelString とほぼ同じです (完全に同じではありません)。しかし、非 Roman スクリプトシステムを使用するシステムでは、GetFInfo は全く違った順序でファイルを返す場合があります。

注意:
アップルコンピュータは、システム機能拡張をロードする順序には依存しないように常に呼びかけてきました。しかし、実際には一定の順序でロードする必要があるシステム機能拡張がたくさんあります。


ユーザが混乱しないように、ボリューム形式や使用しているスクリプトシステムに関係なく、システム機能拡張が必ず同じ順序でロード/実行されるようにするため、システム機能拡張の仕組が、テーブルを使用するように改訂されました。スタートマネージャは、各フォルダのシステム機能拡張を RelString でソートして 1 箇所に納めた、テーブルを構築します。そして、各システム機能拡張はテーブルの順序でロード/実行されます。その結果、システムがどの形式のボリュームからブートされても、どんなスクリプトシステムを使用していても、常に同じ順序でシステム機能拡張がロード/実行されるのです。

スタートマネージャは、他のプログラムがシステム機能拡張のロード機構にアクセスできるよう改訂されました。プログラムで、システム機能拡張のロード/実行処理の監視または制御が可能になりました。

監視と制御

プログラムは ExtensionNotificationProc をインストールして、システム機能拡張のロード処理を監視することができます。個々の ExtensionNotificationProc が呼び出されるのは、最初のシステム機能拡張のロード/実行前、各システム機能拡張のロード/実行の前後両方、最後のシステム機能拡張のロード/実行後です。機能拡張通知ルーチンでは、呼び出しの際に、アイコンの描画、サウンドの再生、システム機能拡張名の表示などさまざまな処理を行うことができます。ロード中のシステム機能拡張の名前をファイルに保存して、クラッシュするシステム機能拡張をデバッグしやすくすることや、システム機能拡張のロード順を記録することもできます。ExtensionNotificationProc はシステム機能拡張のロード/実行の順序を変更することはできません。ExtensionNotificationProcs はいくつでもインストールすることができます。

プログラムは ExtensionTableHandlerProc をインストールして、システム機能拡張のロード処理を制御することができます。個々の ExtensionNotificationProc が呼び出されるのは、最初のシステム機能拡張のロード/実行前、各システム機能拡張のロード/実行の前後両方、最後のシステム機能拡張のロード/実行後です。ExtensionNotificationProc とは違い、ExtensionTableHandlerProc には機能拡張テーブルの所有権が与えられ、システム機能拡張のロード/実行の順序を完全に制御することができます。ExtensionTableHandlerProc をインストールするプログラムは、特定のシステム機能拡張のロード/実行を禁止したり、デフォルト以外のフォルダからシステム機能拡張をロードすることもできます。インストールできる ExtensionTableHandlerProc は 1 つだけです。

ExtensionTableHandlerProc がインストールされていないと、スタートマネージャはデフォルトの機能拡張テーブルハンドラを使用します。このデフォルト機能拡張テーブルハンドラは前バージョンの Mac OS のファイルマネージャのような動作をします (例えば、機能拡張テーブルの構築に使用したフォルダの内容が変わると、機能拡張テーブルを再構築し、あたかもそこでスタートマネージャが GetFInfo を呼び出したように実行が再開されます)。

注意:
ExtensionNotificationProcExtensionTableHandlerProc は起動時のどの時点ででもインストールすることができ、それ以降メッセージを受け取ります。ExtensionTableHandlerProc の場合は、まだインストールが済んでいないシステム機能拡張のロード/実行を制御することができます。


機能拡張テーブル

機能拡張テーブルはシステムヒープ中の再割り当て可能ブロックで、ExtensionTable 構造体が入っています。ExtensionTable は、ExtensionTableHeader とそれに続く ExtensionElements の配列で構成されます。ExtensionTableHeader には、ExtensionTable および ExtensionElements レコードのバージョンを表すフィールド、現在ロード/実行中のシステム機能拡張に対応する ExtensionElements のインデックス、ExtensionElements のサイズ、テーブル中の ExtensionElements の個数が含まれます。ExtensionTable の各 ExtensionElements には、スタートマネージャによってロード/実行されるシステム機能拡張を識別する情報が入っています。

インストール済みの個々の ExtensionNotificationProc には、現在ロード/実行中のシステム機能拡張に対応する ExtensionElements のコピーが渡されます。

システム機能拡張のロード処理を制御する ExtensionTableHandlerProc には、呼び出しの度に毎回 ExtensionTable が渡されます。このハンドラは、ExtensionTable を変更して、システム機能拡張のロードを制御します。

ブート処理

スタートマネージャは、ブート処理の早い時期に (MacsBug のロード後、しかし MacsBug の dcmdSecondaryINIT 時より前)、ExtensionTableHandlerProcExtensionNotificationProc のインストールと削除を行うための API をインストールします。

システム機能拡張のロード/実行前に、スタートマネージャは機能拡張テーブルを作成します。

最初のシステム機能拡張のロード/実行前に、ExtensionTableHandlerProc と各 ExtensionNotificationProc は、システム機能拡張群のロード処理の開始を知らせる extNotificationBeforeFirst メッセージとともに呼び出されます。extNotificationBeforeFirst メッセージで呼び出される ExtensionTableHandlerProc は、どの ExtensionNotificationProc よりも前に呼び出されます。

その後、スタートマネージャは機能拡張テーブルの順序にしたがって各システム機能拡張をロード/実行します。それぞれのシステム機能拡張のロード/実行前に、ExtensionTableHandlerProc とすべての ExtensionNotificationProc は、extNotificationBeforeCurrent メッセージとともに呼び出されます。各システム機能拡張のロード/実行後には、すべての ExtensionNotificationProcExtensionTableHandlerProcextNotificationAfterCurrent メッセージとともに呼び出されます。extNotificationBeforeCurrent メッセージで呼び出される ExtensionTableHandlerProc は、どの ExtensionNotificationProc よりも前に呼び出されます。extNotificationAfterCurrent メッセージで呼び出される ExtensionTableHandlerProc は、どの ExtensionNotificationProc よりも後に呼び出されます。

すべてのシステム機能拡張がロードされた後、すべての ExtensionNotificationProcExtensionTableHandlerProc が、システム機能拡張群のロード処理の完了を知らせる extNotificationAfterLast メッセージとともに呼び出されます。extNotificationAfterLast メッセージで呼び出される ExtensionTableHandlerProc は、最後の ExtensionNotificationProc の後に呼び出されます。

いずれの場合も、ExtensionNotificationProc どうしの呼び出しの相対的な順序は未定義です。

システム機能拡張のロード/実行の監視

INIT、またはシステム機能拡張がロードされる前に実行されるプログラムは、InstallExtensionNotificationProc を呼び出して ExtensionNotificationProc をインストールすることで、システム機能拡張のロード処理を監視することができます。このハンドラはインストール後、次の時点で呼び出されます。

* 最初のシステム機能拡張のロード/実行前 (システム機能拡張のロード/実行処理の開始前にインストールされた場合)
* 各システム機能拡張のロード/実行前
* 各システム機能拡張のロード/実行後
* 最後のシステム機能拡張のロード/実行後

ExtensionNotificationProc は、現在ロード中のシステム機能拡張に対応する ExtensionElement のコピーへのポインタ、ExtensionElementPtr を受け取ります。

注意:
ExtensionElement のデータは読み込み専用です。変更を加えても、ExtensionElement のコピーを変更しているにすぎません。ExtensionNotificationProc の戻りで変更は破棄されます。


ExtensionNotificationProc はいくつでもインストールすることができます。

システム機能拡張のロード/実行の制御

INIT、またはシステム機能拡張がロードされる前に実行されるプログラムは、InstallExtensionTableHandlerProc を呼び出して ExtensionTableHandlerProc をインストールすることで、システム機能拡張のロード処理の制御を行うことができます。ExtensionTableHandlerProc はスタートマネージャが作成したデフォルトの ExtensionTable を返します。

インストール可能な ExtensionTableHandlerProc は 1 つだけです。

いったんインストールされたら、ExtensionTableHandlerProc は、ExtensionTable に対するすべての変更を行う責任があります。しかし、個々のシステム機能拡張をロードする間に extElementIndex フィールドを増加させることだけは不要です。ExtensionTableHandlerProc のインストール後は、システムのデフォルト機能拡張テーブルハンドラは一切 ExtensionTable を管理しません。

ExtensionTableHandlerProc はインストール後、次の場合に呼び出されます。

* 最初のシステム機能拡張のロード/実行前 (システム機能拡張のロード/実行処理の開始前にインストールされた場合)
* 各システム機能拡張のロード/実行前
* 各システム機能拡張のロード/実行後
* 最後のシステム機能拡張のロード/実行後

ExtensionTableHandlerProc と違い、ExtensionTableHandlerProc は、スタートマネージャが使用する、ExtensionTable へのハンドルを受け取ります。これはコピーではありません。

注意:
インストールされた ExtensionTableHandlerProcExtensionTable を変更するか、ExtensionTable で制御されているフォルダの内容が変更されると、ハンドラを削除することができなくなります。こうした変更の後で RemoveExtensionTableHandlerProc を呼び出すと、paramErr エラーが返されます。


ExtensionTableextElementIndex フィールドは、ExtensionTableHandlerProcextNotificationAfterCurrent メッセージで呼び出されたすぐ後に、毎回次の ExtensionElement を指すようインデックスの値が更新されます。

警告:
システム機能拡張のロードを制御している場合、ExtensionElement を指す ExtensionTable.extElements[extElementIndex] の値を変更する安全なタイミングは、ExtensionTableHandlerProcextNotificationAfterCurrent メッセージで呼び出されるときだけです。他のタイミングで ExtensionTableextElementIndex を変更してもかまいませんが、その場合は、ExtensionTable.extElements[extElementIndex] が同じ ExtensionElement を指すよう注意しなければなりません。

リファレンス - 機能拡張テーブルマネージャ

このセクションでは、システム機能拡張のロード処理と実行処理を監視または制御するために使用するテクニックを説明します。

機能拡張テーブルのバージョン (Gestalt)

機能拡張テーブル機構を利用するハンドラをインストールする前に、gestaltExtensionTableVersion セレクタを使って Gestalt を呼び出し、現在インストールされている ExtensionTable のバージョンを調べなければなりません。

enum {
    gestaltExtensionTableVersion = FOUR_CHAR_CODE('etbl') /* ExtensionTable のバージョン */
};


現在 (Mac OS 8.1) の ExtensionTable のバージョンは 1.0.0 です。

enum {
    kExtensionTableVersion = 0x00000100  /* ExtensionTable の現行バージョン (1.0.0) */};


gestaltExtensionTableVersion が未定義だと、機能拡張テーブル機構が存在せず、関連の機能拡張テーブルルーチンも未定義であることを示します。

kExtensionTableVersion と、gestaltExtensionTableVersion か返す値のメジャーバージョン番号が異なる場合、それは機能拡張テーブル機構が大幅に変更されていることを示しており、新しいメジャーバージョンを認知しないコードが機能拡張テーブル機構を利用してはなりません。

kExtensionTableVersion のマイナーバージョン番号が変わっている場合は、ExtensionElement 構造体の定義は拡張されているが、それ以前のマイナーバージョンの kExtensionTableVersion で定義されたフィールドには変更がないことを示します。

ExtensionTable 構造体

ExtensionTable は、ExtensionTableHeader とそれに続く ExtensionElements の配列です。この構造体は、ブート時に、機能拡張テーブル機構が、ロード/実行の対象となるシステム機能拡張をスキャンして構築します。

struct ExtensionTable {
    ExtensionTableHeader     extTableHeader; /* ExtensionTable のヘッダ */    ExtensionElement         extElements[1]; /* ロードする個々の機能拡張を表す要素 */};
typedef struct ExtensionTable    ExtensionTable;
typedef        ExtensionTable    * ExtensionTablePtr;
typedef        ExtensionTablePtr * ExtensionTableHandle;


インストールされた ExtensionTableHandlerProc には、呼び出し時に、現在の ExtensionTable を含む ExtensionTableHandle がパラメータとして渡されます。

ExtensionTableHeader 構造体

ExtensionTableExtensionTableHeader で始まります。

struct ExtensionTableHeader {
    UInt32    extTableHeaderSize;
    UInt32    extTableVersion;
    UInt32    extElementIndex;
    UInt32    extElementSize;
    UInt32    extElementCount;
};
typedef struct ExtensionTableHeader ExtensionTableHeader;

extTableHeaderSize ExtensionTableHeader のサイズ。offsetof(ExtensionTable,extElements[0]) に等しい
extTableVersion ExtensionTable の現行バージョン。gestaltExtensionTableVersion Gestalt セレクタが返す値と同じ
extElementIndex ExtensionElement[] の現在のインデックス (最初の要素はゼロ)。各システム機能拡張がロード/実行された後にスタートマネージャによって増やされる
extElementSize このバージョンの ExtensionTableExtensionElements のサイズ
extElementCount ExtensionTable 内の ExtensionElement レコードの個数


ExtensionTableHandlerProcextTableVersion フィールドのマイナーバージョンをチェックする必要があります。ExtensionTableHandlerProc が書かれた後にこれが変更されていると、extElementSize の値が大きくなっているかもしれません。ExtensionTableHandlerProc がテーブル内の要素を移動または削除するだけのものなら、実行を続けることができます。しかし、新しい要素を作成するものである場合は、ExtensionElements の新しいフィールドを作成する方法がわからないため、ExtensionTableHandlerProc は自身を削除しなければなりません。

この構造体はスタートマネージャ内部で使用され、インストールされている ExtensionTableHandlerProc の呼び出しごとに渡されます。

ExtensionElement 構造体

ExtensionElement 構造体は、スタートマネージャがロード/実行する個々のシステム機能拡張についての情報を格納するために使用します。

struct ExtensionElement {
    Str31               fileName;         /* ファイル名 */    long                parentDirID;      /* ファイルの親ディレクトリの ID */      /* ここからは HParamBlockRec.fileParam バリアントの ioNamePtr 以降のものすべてが入る */    short               ioVRefNum;        /* 常に実ボリューム参照番号 */                                          /* (デフォルトではドライブではない、または作業中の dirID) */    short               ioFRefNum;
    SInt8               ioFVersNum;
    SInt8               filler1;
    short               ioFDirIndex;      /* テーブル内では常に 0 */    SInt8               ioFlAttrib;
    SInt8               ioFlVersNum;
    FInfo               ioFlFndrInfo;
    long                ioDirID;
    unsigned short      ioFlStBlk;
    long                ioFlLgLen;
    long                ioFlPyLen;
    unsigned short      ioFlRStBlk;
    long                ioFlRLgLen;
    long                ioFlRPyLen;
    unsigned long       ioFlCrDat;
    unsigned long       ioFlMdDat;
};
typedef struct ExtensionElement         ExtensionElement;
typedef ExtensionElement *              ExtensionElementPtr;


最初の 2 つの要素は個別のファイルを識別します。残りの要素は HParamBlockRecfileParam バリアントから直接コピーされます。

ExtensionElement は、スタートマネージャが機能拡張フォルダ、コントロールパネルフォルダ、システムフォルダで見つけた各システム機能拡張について作成されます。作成された ExtensionElementExtensionTable にまとめられます。

ExtensionElementPtr は、インストールされている各 ExtensionNotificationProc の呼び出しごとに、パラメータとして渡されます。これが指す ExtensionElement には、現在ロード/実行中のシステム機能拡張に対応する ExtensionElement のコピーが入ります。

機能拡張通知メッセージコード

ExtensionNotificationProc または ExtensionTableHandlerProc には呼び出しの際、以下のメッセージパラメータが渡されます。

enum {
    extNotificationBeforeFirst   = 0, /* システム機能拡張のロード開始前 */    extNotificationAfterLast     = 1, /* 全システム機能拡張のロード完了後 */    extNotificationBeforeCurrent = 2, /* extElementIndex が示すシステム */                                      /* 機能拡張のロード前 */    extNotificationAfterCurrent  = 3  /* extElementIndex が示すシステム */                                      /* 機能拡張のロード後 */};

ExtensionNotificationProc

pascal void MyExtensionNotificationProc( UInt32 message, void *reserved,
                                         ExtensionElementPtr extElement );

message 入力 4 つの ExtensionNotification メッセージコードの 1 つ
reserved 将来のため予約
extElement 入力 現在ロード/実行中のシステム機能拡張の ExtensionElement のコピー

注意:
extElement は、extNotificationBeforeFirstextNotificationAfterLast メッセージでは無効です。


ExtensionNotificationProc は、現在ロード中のシステム機能拡張に対応する ExtensionElement のコピーを指す ExtensionElementPtr を受け取ります。

注意:
ExtensionElement のデータは変更できません。変更を行ったにしても、ExtensionElement のコピーを変更しているにすぎません。ExtensionNotificationProc の戻りで変更は破棄されます。


ExtensionNotificationProc はいくつでもインストールすることができます。

注意:
ExtensionNotificationProcRemoveExtensionNotificationProc を呼び出すことはできません。ExtensionNotificationProc が自身を削除する必要がある場合は、例えば、Notification Manager タスクをインストールして、後でそのタスクのなかで ExtensionNotificationProc を削除するなどの方法を取らなければなりません。



ExtensionTableHandlerProc

pascal void MyExtensionTableHandlerProc( UInt32 message, void *reserved,
                                         ExtensionTableHandle extTableHandle );

message 入力 4 つの ExtensionNotification メッセージコードの 1 つ
reserved 将来のため予約
extTableHandle 入力 ロード予定のすべてのシステム機能拡張を含む

ExtensionTableHandlerProc は、起動時にスタートマネージャが作成した ExtensionTable へのハンドルを受け取ります。ExtensionTableHandlerProc がインストールされると、システムのデフォルトハンドラは ExtensionTable の管理をそれ以上行いません。ExtensionTableHandlerProc はインストールされている間、システム機能拡張のロード/実行の間に extElementIndex フィールドが自動的に更新されることを除いては、ExtensionTable に対するすべての変更を行う責任があります。

注意:
ExtensionTableHandlerProc のインストール後に、ExtensionTable またはそれに含まれるフォルダの内容が変更された場合、RemoveExtensionTableHandlerProc を呼び出すことはできません。


extElementIndexフィールドは、ExtensionTableHandlerProcextNotificationAfterCurrent メッセージで呼び出されたすぐ後に、毎回次の ExtensionElement を指すようインデックスの値が更新されます。

警告:
システム機能拡張のロードを制御している場合、ExtensionElement を指す ExtensionTable.extElements[extElementIndex] の値を変更する唯一安全な時点は、ExtensionTableHandlerProcextNotificationAfterCurrent メッセージで呼び出されるときです。他の時点で ExtensionTableextElementIndex を変更してもかまいませんが、その場合は、ExtensionTable.extElements[extElementIndex] が同じ ExtensionElement を指すよう注意しなければなりません。


インストールされている ExtensionTableHandlerProc は常に、extNotificationBeforeFirst および extNotificationBeforeCurrent メッセージで呼び出される最初のハンドラです。また、ExtensionTableHandlerProc は、extNotificationAfterLast および extNotificationAfterCurrent メッセージで呼び出される最後のハンドラです。

インストールできる ExtensionTableHandlerProc は 1 つだけです。

InstallExtensionNotificationProc

OSErr InstallExtensionNotificationProc( ExtensionNotificationUPP extNotificationProc )

パラメータ:
extNotificationProc 入力 インストールする ExtensionNotificationUPP

結果:
noErr 0 ExtensionNotificationUPP はインストールされました
paramErr -50 ExtensionNotificationUPP はすでにインストールされています
memFullErr -108 ExtensionNotificationUPP をインストールできるメモリがありません

ExtensionNotificationUPP をインストールします。

複数の ExtensionNotificationProcs をインストールすることができます。

RemoveExtensionNotificationProc

OSErr RemoveExtensionNotificationProc (ExtensionNotificationUPP
                                       extNotificationProc)

パラメータ:
extNotificationProc 入力 削除する ExtensionNotificationUPP

結果:
noErr 0 ExtensionNotificationUPP が削除されました
paramErr -50 ExtensionNotificationUPP が見つからないか、RemoveExtensionNotificationProcExtensionNotificationProc の中から呼び出されました

ExtensionNotificationUPP を削除します。

注意:
ExtensionNotificationProcsRemoveExtensionNotificationProc を呼び出すことはできません。


InstallExtensionTableHandlerProc

OSErr InstallExtensionTableHandlerProc( ExtensionTableHandlerUPP extMgrProc,
                                        ExtensionTableHandle * extTable)

パラメータ:
extMgrProc 入力 インストールする ExtensionTableHandlerUPP
extTable 入力 InstallExtensionTableHandlerProc に現在の ExtensionTableHandle を返してもらうための ExtensionTableHandle へのポインタ。ハンドルは呼び出し側が保持する訳ではないので、破棄してはいけません。ただし、テーブル内の extElementIndexextElementCountExtensionElements は変更できます。

結果:
noErr 0 ExtensionTableHandlerUPP はインストールされました
paramErr -50 別の ExtensionTableHandlerUPP がすでにインストールされています
memFullErr -108 ExtensionTableHandlerUPP をインストールするだけのメモリがありません

ExtensionTableHandlerUPP をインストールします。

インストールできる ExtensionTableHandlerProc は 1 つだけです。

RemoveExtensionTableHandlerProc

OSErr RemoveExtensionTableHandlerProc( ExtensionTableHandlerUPP extMgrProc )

パラメータ:
extMgrProc input 削除する ExtensionTableHandlerUPP

結果:
noErr 0 ExtensionTableHandlerUPP が削除されました。
paramErr -50 ExtensionTableHandlerUPP はインストールされていないか、現在の ExtensionTable は、オリジナルの ExtensionTable ではありません。

ExtensionNotificationUPP を削除します。その後はデフォルトのハンドラに制御が戻ります。
注意:
ExtensionTableHandlerProc のインストール後に、ExtensionTable またはそれに含まれるフォルダの内容が変更された場合、RemoveExtensionTableHandlerProc を呼び出すことはできません。

まとめ - 機能拡張テーブルマネージャ

注意:
ここで定義されたものはすべて Universal Interfaces 3.1 に入っています。


定数

enum {
    gestaltExtensionTableVersion = FOUR_CHAR_CODE('etbl')  /* ExtensionTable のバージョン */};

enum {
    kExtensionTableVersion      = 0x00000100  /* ExtensionTable の現行バージョン (1.0.0) */};

/* ExtensionNotification メッセージコード */
enum {
    extNotificationBeforeFirst   = 0, /* システム機能拡張のロード開始前 */    extNotificationAfterLast     = 1, /* 全システム機能拡張のロード完了後 */    extNotificationBeforeCurrent = 2, /* extElementIndex が示すシステム */                                      /* 機能拡張のロード前 */    extNotificationAfterCurrent  = 3  /* extElementIndex が示すシステム */                                      /* 機能拡張のロード後 */};


データ型

struct ExtensionElement {
    Str31               fileName;         /* ファイル名 */    long                parentDirID;      /* ファイルの親ディレクトリの ID */                                          /* ここからは HParamBlockRec.fileParam バリアントの */                                          /* ioNamePtr 以降のものすべてが入る */    short               ioVRefNum;        /* 常に実ボリューム参照番号 */                                          /* (デフォルトではドライブではない、または作業中の dirID) */
    short               ioFRefNum;
    SInt8               ioFVersNum;
    SInt8               filler1;
    short               ioFDirIndex;      /* テーブル内では常に 0 */    SInt8               ioFlAttrib;
    SInt8               ioFlVersNum;
    FInfo               ioFlFndrInfo;
    long                ioDirID;
    unsigned short      ioFlStBlk;
    long                ioFlLgLen;
    long                ioFlPyLen;
    unsigned short      ioFlRStBlk;
    long                ioFlRLgLen;
    long                ioFlRPyLen;
    unsigned long       ioFlCrDat;
    unsigned long       ioFlMdDat;
};
typedef struct ExtensionElement         ExtensionElement;
typedef ExtensionElement *              ExtensionElementPtr;
struct ExtensionTableHeader {
    UInt32    extTableHeaderSize;    /* ExtensionTable のヘッダのサイズ */                                     /* offsetof(ExtensionTable,extElements[0]) と等しい */    UInt32    extTableVersion;       /* ExtensionTable の現行バージョン */                                     /* gestaltExtensionTableVersion Gestalt セレクタが返す値と同じ */
    UInt32    extElementIndex;       /* ExtensionElement の現在のインデックス */                                     /* (最初の要素はゼロ) */    UInt32    extElementSize;        /* ExtensionElement のサイズ */    UInt32    extElementCount;       /* テーブル中の ExtensionElement */                                     /* レコードの個数 (1 から数える) */};

typedef struct ExtensionTableHeader     ExtensionTableHeader;
struct ExtensionTable {
    ExtensionTableHeader   extTableHeader;          /* ExtensionTableHeader */    ExtensionElement       extElements[1];  /* ロードする個々の機能拡張を表す要素 */};
typedef struct ExtensionTable           ExtensionTable;
typedef ExtensionTable *                ExtensionTablePtr;
typedef ExtensionTablePtr *             ExtensionTableHandle;


ルーチン

OSErr   InstallExtensionNotificationProc( ExtensionNotificationUPP  extNotificationProc)
OSErr   RemoveExtensionNotificationProc( ExtensionNotificationUPP  extNotificationProc)

OSErr   InstallExtensionTableHandlerProc( ExtensionTableHandlerUPP  extMgrProc,
                                          ExtensionTableHandle *    extTable)

OSErr   RemoveExtensionTableHandlerProc( ExtensionTableHandlerUPP  extMgrProc )


結果コード
noErr 0 ExtensionNotificationUPP のインストールまたは削除が成功しました。
paramErr -50 パラメータにエラーがありルーチンの実行が継続できません。
memFullErr -108 ExtensionNotificationUPP をインストールまたは削除するためのメモリがありません。