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


Technote 1041

Inside Macintosh: Files Errata


このテクニカルノートでは、『Inside Macintosh: Files』の誤植を訂正し、内容の不備を補足します。

目次

第 1 章 - File Management の概要

第 2 章 - File Manager

第 3 章 - 標準ファイルパッケージ

第 4 章 - Alias Manager

第 5 章 - Disk Initialization Manager

参考文献

ダウンロード



第 1 章 - File Management の概要

FSpExchangeFilesPBExchangeFiles - 何が交換されるか

1-53 ページ、FSpExchangeFiles

このトピックの詳細については、第 2 章の正誤表を参照してください。

GetVInfo に関する追加検討事項

1-56 ページ、GetVInfo

このトピックの詳細については、第 2 章の正誤表を参照してください。

先頭ページに戻る


第 2 章 - File Manager

パス名の規則が完全に説明されていない

2-27 ページから 2-28 ページ、名前とパス名

次のような Macintosh のパス名の特性に注意してください。

  • フルパス名がコロンで始まることはありませんが、フルパス名には少なくとも 1 つのコロンが含まれている必要があります。
  • 単一のファイルまたはディレクトリの名前である場合を除き、部分パス名は常にコロンセパレータで始まります。
  • フルパス名または部分パス名の末尾にあるコロンセパレータは、それがボリュームへのフルパス名である場合を除き、無視されます。
  • ボリュームへのフルパス名では名前の末尾にコロンセパレータが必要です。
  • 連続するコロンセパレータは、あるディレクトリからその親ディレクトリにレベルを上げるために使用できます。連続する 2 つのコロンセパレータはレベルを 1 つ上げ、連続する 3 つのコロンセパレータはレベルを 2 つ上げます。レベルの上昇はファイルではなく、ディレクトリからのみ始まります。

以上をまとめると、パス名の先頭文字がコロンであるか、パス名にコロンが含まれていない場合、それは必ず部分パス名です。そうでない場合はフルパス名です。

表 2-10 に記載されていない行がある

2-35 ページ、ファイルシステム仕様レコードの作成

表 2-10 に次の行を追加してください。

作業ディレクトリ参照番号 ディレクトリ ID 空白文字列または NIL ターゲットオブジェクトは、dirID のディレクトリ ID によって指定されるディレクトリです。

起動時のデフォルトディレクトリの説明に不備がある

2-36 ページ、デフォルトのボリュームとディレクトリの取り扱い

第 1 段落の最後の文を次の文に置き換えてください。

「アプリケーションが起動するとき、そのデフォルトディレクトリはアプリケーションが格納されているディレクトリに設定されます。その後は、アプリケーションが任意のディレクトリをそのデフォルトディレクトリとして指定することができます。」

マスターディレクトリブロックの drXTFlSize および drCTFlSize フィールドの説明に不備がある

2-62 ページ、マスターディレクトリブロック

フィールドの記述を次のように変更してください。

drXTFlSizeエクステントオーバーフローファイルのサイズ (バイト単位)。
drCTFlSizeカタログファイルのサイズ (バイト単位)。

マップノードのマップレコードは 492 バイト (494 バイトではなく) を占有する

2-69 ページ、マップノード

「マップノード」セクションの第 2 および第 3 段落を次の段落に置き換えてください。

「マップノードは 1 つのノード記述子と1つのマップレコードから構成されます。このマップレコードは、ヘッダーノードに含まれているマップレコードの続きであり、492 バイトを占有します (ノード全体の 512 バイトからノード記述子の 14 バイトとノードの末尾にある 2 つのレコードオフセットそれぞれに対する 2 バイトを差し引き、その結果をロングワードの倍数に切り下げた値)。(注意: HFS ファイルシステムの B ツリーマネージャが一度に読み込むビットマップ情報はロングワードに相当します。) したがって、1 つのマップノードは 3936 個のノードに対応するマッピング情報を含むことができます。

B ツリーに 5984 (つまり、2048 + 3936、約 25,000 ファイルの情報を十分に格納できる) を超えるノードが含まれている場合、File Manager は第 2 のマップノードを使用します。このマップノードのノード番号は、先頭のマップノードのノード記述子に含まれる ndFLink フィールドに格納されます。さらにそれ以上のマップノードが必要な場合は、同様の方法でそれぞれの追加マップノードが前のマップノードにリンクされます。」

vcbAtrb のボリュームキャッシュコントロールビット

2-79 ページ、ボリュームコントロールブロック

System 7.5 またはそれ以降の vcbAtrb には次のビット定義を追加してください。

ビット意味
10ボリュームのブロックがキャッシュされない場合にセットします (System 7.5 またはそれ以降のみ)。このビットにより、RAM ディスクボリュームにアクセスして、File Manager キャッシュをバイパスすることが可能になります。これは、File Manager によるボリュームへのすべての読み書きに対して noCache ビット (ioPosMode のビット 5) をセットするのと同じ効果があります。非ブロックアラインリクエストがキャッシュを介してアクセスされることもあります。

HFSボリュームが System 7.5 またはそれ以降を使ってマウントされるとき、File Manager は "Return Drive Info" _Control 呼び出し (csCode=23) を使ってディスクドライバを呼び出します。さらに、File Manager は csParam の下位バイト (ビット 0-7) を見て、ドライブタイプが ramDiskType (16, $10) または romDiskType (17, $11) であるかどうかチェックします。もしそうであれば、VCB の vcbAtrb フィールドの vcbAtDontCache ビットをセットします。これにより、RAM または ROM ディスクボリュームにアクセスして、File Manager キャッシュをバイパスすることが可能になります。これは、File Manager によるボリュームへのすべての読み書きに対して noCache ビット (ioPosMode のビット 5) をセットするのと同じ効果があります。非ブロックアラインリクエストがキャッシュを介してアクセスされることもあります。

ドライバに関する注意: ドライバが vcbAtrbvcbAtDontCache ビットを直接的に変更するのは避けてください。RAM または ROM ディスクに対応するドライバでは、_Control csCode 23 をサポートし、csParam の下位バイトで ramDiskType (16, $10) または romDiskType (17, $11) を取得することで、それが RAM または ROM ディスクであると判断するようにします。他のディスクドライバが vcbAtDontCache ビットをセットしてはいけません。そうでないと、今後 File Manager キャッシュに加えられることになっている改善がそれらのドライブでは無効になってしまいます。

ボリュームコントロールブロックの vcbXTAlBks および vcbCTAlBks フィールドの説明に不備がある

2-81 ページ、ボリュームコントロールブロック

フィールドの説明を次のように変更してください。

vcbXTAlBksエクステントオーバーフローファイルのサイズ (アロケーションブロック内の)。
vcbCTAlBksカタログファイルのサイズ (アロケーションブロック内の)。

3.5 インチフロッピーディスク上では使用されない dQDrvSiz フィールド

2-85 ページ、ドライブキュー

注意
ボリュームが .Sony ドライバによって所有されている 3.5 インチフロッピーディスクの場合、CODE>dQDrvSiz および dQDrvSiz2 フィールドは有効でなくなります。.Sony ドライバによって所有されている 3.5 インチフロッピーディスクのサイズを取得するには、まず Return Format List (csCode= 6) Status 呼び出しを試し、Return Format List に statusErr (-18) が発生する場合は、DriveStatus を使って、DrvSts レコードの twoSideFmt フィールドをチェックして、ディスクが 800 のブロック (twoSideFmt = 0) と 1600 (twoSideFmt = -1) のブロックのどちらを持つかを決定します。Return Format List Status 呼び出しの詳細については、テクニカルノート「DV 17 - Sony Driver : What Your Sony Drives For You」を参照してください。

ParamBlockRec, HParamBlockRec、および CInfoPBRecioFlAttrib ビットの明確化

2-90 ページ、基本的な File Manager パラメータブロック、fileParam バリアントに対するフィールドの説明
2-96 ページ、HFS パラメータブロック、fileParam バリアントに対するフィールドの説明
2-102 ページ、カタログ情報パラメータブロック、両方のバリアントに共通なフィールドの説明

ファイルの場合、ioFlAttrib の各ビットは次のような意味を持ちます。

ビット意味
0ファイルがロックされている場合にセットします。PBHSetFLock または PBHRstFLock 関数を使って変更することができます。
1予約されています。
2リソースフォークがオープンしている場合にセットします。
3データフォークがオープンしている場合にセットします。
4ディレクトリの場合にセットします (ファイルの場合は常にクリアされています)。
5予約されています。
6AppleShare サーバがファイルの "コピープロテクト" を行っている場合にセットします。サーバが afpGetFileDirParms によって返される CopyProtect ビットをセットするとき、AppleShare 外部ファイルシステムコードによってセットします。
7ファイル (またはフォーク) がオープンしている場合にセットします。

ディレクトリの場合、ioFlAttrib の各ビットは次のような意味を持ちます。

ビット意味
0ディレクトリがロックされている場合にセットします。ボリュームが共有されているときは、PBHSetFLock または PBHRstFLock 関数を使って変更することができます。
1予約されています。
2ディレクトリがディレクトリ階層の共有領域内にある場合にセットします。
3ディレクトリが任意のユーザによってマウントされている共有ポイントである場合にセットします。
4ディレクトリの場合にセットします (ディレクトリの場合は常にセットされています)。
5ディレクトリが共有ポイントである場合にセットします。PBShare および PBUnshare によってセットまたはクリアすることができます。
6予約されています。
7予約されています。

ioACUser はいくつかのインタフェースファイルの中では filler2 になっている

2-100 および 2-103 ページ、カタログ情報パラメータブロック
2-191 ページ、PBGetCatInfo

注意
ioACUser フィールドは CInfoPBRec パラメータブロックのオフセット31 ($1F) にあります。Files インタフェースの大部分のバージョン (Files.h、Files.p など) では、オフセット 31 のフィールドは filler2 です。この問題は Files インタフェースの最新バージョンでは解決されています。

VolMountInfoHeader データ構造体にはフラグワードが含まれている

2-110 ページ、ボリュームマウンティング情報レコード

VolMountInfoHeader データ構造体はフラグワードを含むように拡張されました。現在、このデータ構造体は次のように定義されています。


 struct VolMountInfoHeader
 {
     short       length;  /* ロケーションデータ (自分自身を含む) の長さ */
     VolumeType  media;   /* メディアのタイプ */
     short       flags;   /* Apple が予約している上位バイト */
                          /* ファイルシステム固有の使用のために予約されている下位バイト */
     /* 可変長データが続く */
 };

フラグワード内では、ビット 14 と 15 が定義されています。フラグワードの上位バイトに含まれるその他すべてのビットはクリアしたままにしておきます。フラグワードの下位バイトに含まれるビットはファイルシステムに固有です。たとえば、AppleShare 外部ファイルシステムでは、サーバの起動メッセージが表示されるか抑制されるかを判断するためにビット 0 を使用します。

フラグワードのビット 15 は、VolumeMount リクエストを受け付けるファイルシステムにユーザとのやり取りが実行できるかどうかを通知します。ビット 15 がセットされていると、ファイルシステムはユーザとのやり取りを実行する必要はありません。ビット 15 がクリアされていると、ファイルシステムは FSM (File System Manager) によって供給されるメカニズムを介してユーザとのやり取りを実行できます。

フラグワードのビット 14 を使用すると、VolumeMount リクエストが正常に終了した場合でも、ファイルシステムは渡された VolMountInfo レコードを更新する必要があることを VolumeMount の呼び出し側に指示することができます。プログラムでは、VolumeMount を呼び出す前にフラグワードのビット 14 を確実にクリアしておく必要があります。また、戻り値としてビット 14 がセットされた場合は、PBGetVolMountInfoSize およびPBGetVolMountInfo を呼び出して VolMountInfo レコードを更新する必要があります。VolumeMount の実行が正常に終了しない場合は、フラグワードのビット 14 を無視してください。

注意深い読者なら、MatchAlias 関数呼び出しに応答するとき、Alias Manager はフラグワードのビット 14 および 15 を使って、ファイルシステムとのやり取りを行う必要があることに気づくはずです。

PBRead および PBWrite リクエストによる ioPosMode の使い方

2-121 ページ、PBRead
2-122 ページ、PBWrite

PBRead および PBWrite 関数は ioPosMode フィールドへのアクセスを許可するため、高レベルな FSRead および FSWrite 関数と比較すると、読み書きオペレーションに対するはるかに強力な制御をプログラムに提供します。

ioPosMode のビット 0 と 1 はファイルのデータの読み書きを開始する場所を指定します。ioPosMode でビット 0 と 1 にセットできる値は以下のとおりです。

定数説明
fsAtMark0ioPosOffset は無視されます。オペレーションは現在のマークから開始されます。
fsFromStart1ioPosOffset はファイルの先頭からのオフセットです。
fsFromLEOF2ioPosOffset はファイルの論理的な末尾からのオフセットです。
fsFromMark3ioPosOffset は現在のマークからのオフセットです。

ioPosMode のビット 4 と 5 は、ファイルが保存されているボリュームへのリクエストを処理するファイルシステムに渡されるキャッシュの使用に関するヒントです。ビット 4 はデータをキャッシュに格納することを要求します。また、ビット 5 はデータをキャッシュに格納しないことを要求します。ビット 4 と 5 は相互に排他的であり、両方のビットを同時にセットすることはできません。ただし、どちらのビットもセットされていない場合、プログラムはデータをキャッシュに格納するかどうかを考慮しないことを示します。ioPosMode でビット 4 と 5 にセットできる値は以下のとおりです。

定数説明
(定数なし)0このリクエストをキャッシュに格納するかどうかを考慮しません。
pleaseCacheMask16可能な場合は、このリクエストをキャッシュに格納してください。
noCacheMask32このリクエストをキャッシュに格納しないことを期待します。

注意
特定のファイルシステムでは、キャッシュの使用に関するヒントビットの一方または両方を無視する場合があります。つまり、noCache ビットをセットした場合にキャッシュを使用することもあれば、pleaseCache ビットをセットした場合にキャッシュを使用しないこともあります。また、どんな場合にもキャッシュを使用したり、キャッシュをまったく使用しないこともあります。ただし、プログラムが両方のビットをクリアしたままにしておくと、これらのビットを考慮するファイルシステムは、読み書きしたデータがプログラムによって再度必要とされるかどうかを判断できなくなります。

ioPosMode のビット 6 (rdVerify) は、読み込み (書き込みではなく) がデータソースから直接行われ、メモリ内のデータと比較して検証が行われることを要求します。その結果、rdVerify がセットされた読み込みリクエストを受け取ったファイルシステムは、データの一部が格納されているかもしれないキャッシュを破棄し、そのデータソース (ローカルボリュームの場合、データソースはディスクドライバになります) にデータを再度要求することになります。データソースがディスクドライバの場合、ファイルシステムは rdVerify リクエストをそのディスクドライバに渡し、ディスクドライバは同じ処理を実行します。つまり、データ (ディスクハードウェア上のキャッシュを含む) の一部が格納されている可能性のあるキャッシュを破棄して、そのソース (ディスクハードウェア) にデータを再度要求します。rdVerify の背後にあるアイデアは、プログラムはボリュームにデータを書き込み、さらにディスクボリュームのデータを書き込みバッファに格納されているデータと比較するようにファイルシステムに要求することができるということです。Finder はファイルをフロッピーディスクにコピーするときだけ、このテクニックを使用します。

重要
HFS ファイルシステムの現在のバージョンには、rdVerify リクエストに悪影響を与えるバグが存在します。ディスクのデータをメモリ内のデータと比較するのではなく、HFS ファイルシステムは実際にはリクエストに含まれるフル 512 バイトブロックをソースデバイスからバッファに読み込んで、比較を行う代わりにオリジナルのデータを上書きしています。たいていの場合、これはデバイスに書き込まれたデータとまったく同じですが、メディアまたはハードウェア障害のために何らかのデータエラーが発生していると、オリジナルの書き込みデータバッファが壊れてしまう可能性があります。この問題を回避するには、まず最初に書き込みデータバッファのコピーを作成し、オリジナルのデータバッファではなくコピーに対して rdVerify オペレーションを実行します。そして最後にコピーとオリジナルのデータバッファを比較して、書き込まれたデータが読み込まれたデータとまったく同じであることを検証します。

ioPosMode のビット 7 は newLine モードに対するリクエストです。ビット 7 がセットされていると、ioPosMode の上位バイトは、その文字が null ($00) であっても newLine 文字になります。ビット 7 がセットされているときは、次のいずれかの条件が整うと読み込みが中止されます。

  • ioReqCount バイトが読み込まれた。
  • ファイルの末尾に達した。
  • newLine 文字が読み込まれた。newLine 文字が検出されると、それは ioBuffer に格納されている最後の文字になり、ioActCount はそれを含むことになります。

newLine モードを使用するとき、HFS ファイルシステムは 1 度にファイルの 1 ブロック (512 バイト) をファイルシステムキャッシュブロック (ioBuffer によって指されるユーザバッファではなく) に読み込み、各バイトで newLine 文字を検索するたびにそのデータを 1 バイトずつユーザバッファにコピーします。newLine モードでは、ファイルは 1 度に 1 ブロックずつ読み込まれるため、これは最も時間のかかるファイルの読み込み方法といえます。

GetVInfo に関する追加検討事項

2-137 ページ、GetVInfo

ボリュームを指定する drvNum パラメータは、ドライブ番号、ボリューム参照番号、0 (デフォルトのボリューム)、または作業ディレクトリ番号のいずれかになります。volName パラメータは Str27 バッファを指すか、NIL に設定されている必要があります。freeBytes パラメータは、2GB を超える空き領域を含むボリュームでは正確でなくなります。

いくつかのパラメータブロックには不必要な ioCompletion フィールドがある

2-142 ページ、PBOffLine
2-219 ページ、PBGetVolMountInfoSize
2-220 ページ、PBGetVolMountInfo
2-223 ページ、PBVolumeMount

これらのルーチンに対するパラメータブロックでは、入力フィールドとしての ioCompletion フィールドをリストする必要はありません。これらのルーチンは同期的にのみ実行できるため、ioCompletion フィールドは常に無視されます。

PBHGetVInfo に関して特に検討すべき問題

2-145 ページ、PBHGetVInfo

次の「特に検討すべき問題」を追加してください。

ioVolIndex の値が負の場合、File Manager は標準的な方法で ioNamePtrioVRefNum を使って、ボリュームを決定します。しかし、PBHGetVInfoioNamePtr に渡したアドレスを持つバッファにボリューム名を返すため、入力したパス名は変更されます。入力パス名を変更したくない場合は、そのコピーを作成して、そのコピーを PBHGetVInfo に渡します。

PBHGetVInfo によって返されるパス名はコロンを含んでいないため、ボリュームへのフルパス名ではありません。

古いプログラムとの互換性を維持するため、PBHGetVInfo によって返される値の一部はボリュームの VCB (Volume Control Block) に格納されるものではありません。特に、次の点に注意してください。

  • ioVNmAlBlks および ioVFrBlk は、ioVAlBlkSiz を乗ずるときに常に 2GB 未満になる値に制限されます。
  • ioVNmAlBlks には、カタログおよびエクステントオーバーフローファイルで使用されるアロケーションブロックが含まれないことがあります。
  • HFS および HFS Plus ボリュームの両方で ioVSigWord には $4244 が返されます。

制限を受けない総計バイトカウント、空きバイトカウント、および実際の ioVSigWord が必要な場合は、PBHGetVInfo の代わりに PBXGetVolInfo を使用します。

FSpGetFInfo はディレクトリとともに動作しない

2-160 ページ、FSpGetFInfo

FSpGetFInfo 関数を使用すると、ファイルに関する Finder 情報を取得することはできますが、ディレクトリに関する Finder 情報を取得することはできません。

FSpSetFInfo はディレクトリとともに動作しない

2-160 ページ、FSpSetFInfo

FSpSetFInfo 関数を使用すると、ファイルに関する Finder 情報を設定することはできますが、ディレクトリに関する Finder 情報を設定することはできません。

FSpExchangeFilesPBExchangeFiles - 何が交換されるか

2-165 ページ、FSpExchangeFiles
2-206 ページ、PBExchangeFiles

FSpExchangeFiles 関数は、2 つのファイルを対象にボリュームのカタログおよびファイルコントロールブロック (どちらかのファイルがオープンしている場合) の情報を変更することで、それぞれのファイルに含まれるデータを交換します。特に、次のような変更が加えられます。

2 つのファイルのボリュームカタログエントリに含まれる次のフィールドが交換されます ( PBExchangeFiles から見て)。

ioFlStBlkデータフォークの先頭のアロケーションブロック
ioFlLgLenデータフォークの論理的な end-of-file
ioFlPyLenデータフォークの物理的な end-of-file
ioFlRStBlkリソースフォークの先頭のアロケーションブロック
ioFlRLgLenリソースフォークの論理的な end-of-file
ioFlRPyLenリソースフォークの物理的な end-of-file
ioFlMdDat最後に修正された日付と時刻

2 つのファイルのデータフォークとリソースフォークが交換されます。

2 つのファイルに対する任意のオープンファイルコントロールブロックに含まれる次のフィールドが交換されます。

fcbFlNumファイルID番号
fcbDirIDファイルの親ディレクトリ ID
fcbCNameファイルの名前

注意
ファイルの名前と親ディレクトリ ID はファイルコントロールブロック内で交換されるため、アプリケーションは 2 つのファイルへの任意のオープン参照番号を交換しなければならなくなります。

他のプログラムが交換されるファイルの一方または両方へのアクセスパスをオープンしている可能性があるため、FSpExchangeFiles を呼び出す前に、アプリケーションでは両方のファイルへの排他的な読み書きアクセス権 (fsRdWrPerm) を確立してください。両方のファイルへの排他的な読み書きアクセスを行うことで、他のアプリケーションは交換されるファイルの一方または両方への書き込みアクセスを取得できなくなるため、FSpExchangeFiles が他のアプリケーションに影響を与えないことが保証されます。

注意
FSpExchangeFiles はファイルロック属性を考慮しません。このため、一方または両方のファイルがロックされている場合でも交換が実行されます。FSpExchangeFiles を呼び出す前に、両方のファイルへの排他的な読み書きアクセスを取得することで、ロックされているファイルは書き込みアクセスによってオープンできなくなるため、ファイルのロックを確実に解除することができます。

HOpenDF、PBHOpenDF、および paramErr 結果コード

2-169 ページ、HOpenDF
2-169 ページ、PBHOpenDF

HOpenDF または PBHOpenDF 関数にエラーが発生して paramErr 結果コードが返される場合 (HOpenDF または PBHOpenDF が使用可能でないことを示しています)、同じパラメータを HOpen または PBHOpen に渡してリクエストを再試行してください。たとえば、次のようなコードを実行します。


     error = HOpenDF(vRefNum, dirID, fileName, permission, &refNum);
     if ( error == paramErr )
     {
         /* HOpenDF がサポートされていなければ、HOpen を使用 */
         error = HOpen(vRefNum, dirID, fileName, permission, &refNum);
     }

パラメータブロックに ioFVersNum フィールドがない

2-183 ページ、PBHOpenDF
2-184 ページ、PBHOpenRF
2-185 ページ、PBHOpen
2-187 ページ、PBHCreate
2-189 ページ、PBHDelete
2-194 ページ、PBHGetFInfo
2-196 ページ、PBHSetFInfo
2-197 ページ、PBHSetFLock
2-198 ページ、PBHRstFLock
2-199 ページ、PBHRename

パラメータブロックに ioFVersNum フィールドが抜けています。ioFVersNum はゼロに初期化してください。というのも、アクセスされるボリュームが MFS (Macintosh File System) ボリュームである場合、これらの呼び出しは時代遅れになってしまった MFS コードを実行するためです。

パラメータブロックに ioMisc フィールドがない

2-183 ページ、PHHOpenDF
2-184 ページ、PHHOpenRF
2-185 ページ、PBHOpen

パラメータブロックに ioMisc フィールドが抜けています。ioMisc は、PHHOpenDF、PHHOpenRF、または PBHOpen を呼び出す前にゼロに初期化する必要があります。一部の Macintosh モデルで ioMisc をゼロに初期化できないと、システムがクラッシュする原因になります。

PBGetCatInfoioFDirIndex の使用規則

2-191 ページ、PBGetCatInfo

PBGetCatInfoioFDirIndex の使用規則に関する説明を次のように変更してください。

PBGetCatInfo 関数は次の規則にしたがってファイルまたはディレクトリを選択します。

  • ioFDirIndex の値が正の場合、ioNamePtr は入力パラメータとして使用されず、PBGetCatInfo は、ioVRefNumioDirID によって指定されるディレクトリ (ioVRefNum がボリューム参照番号またはドライブ番号で、ioDirID が 0 の場合、これはルートディレクトリになります) 内でディレクトリインデックスが ioFDirIndex であるファイルまたはディレクトリに関する情報を返します。ioNamePtr が NIL でない場合、このポインタはファイルまたはディレクトリ名が返されることになる Str31 バッファを指している必要があります。

  • ioFDirIndex の値が 0 の場合、PBGetCatInfo は、ioVRefNumioDirID によって指定されるディレクトリ (ここでも、ioVRefNum がボリューム参照番号またはドライブ番号で、ioDirID が 0 の場合、これはルートディレクトリになります) 内で ioNamePtr によって指定されるファイルまたはディレクトリに関する情報を返します。

  • ioFDirIndex の値が負の場合、ioNamePtr は入力パラメータとして使用されず、PBGetCatInfo は、ioVRefNumioDirID によって指定されるディレクトリ (ここでも、ioVRefNum がボリューム参照番号またはドライブ番号で、ioDirID が 0 の場合、これはルートディレクトリになります) に関する情報を返します。ioNamePtr が NIL でない場合、このポインタはディレクトリ名が返されることになる Str31 バッファを指している必要があります。

パラメータブロックに ioNamePtr フィールドがない

2-219 ページ、PBGetVolMountInfoSize
2-220 ページ、PBGetVolMountInfo
2-223 ページ、PBHGetLogInInfo

パラメータブロックに ioNamePtr フィールドが抜けています。ioNamePtrioVRefNum は、両方ともボリュームを指定するために使用します。

ioForeignPrivIDirIDPBGetForeignPrivsPBSetForeignPrivs では LongInt である

2-233 および 2-234 ページ

ioForeignPrivIDirID が実際に LongInt であるとき、パラメータブロックは ioForeignPrivIDirID を整数として表示します。

リクエストの実行順序

2-239 ページ、MyCompletionProc の後の新しい情報

ファイル共有または AppleShare ファイルサーバがアクティブになっているとき、File Manager は任意の順序でリクエストを実行します。これは、前に実行されたリクエストの結果に依存するリクエストが存在する場合に、第 1 のリクエストを完了する前にプログラムが第 2 のリクエストを実行するとエラーが発生するということを意味します。たとえば、書き込みリクエストを実行した後で同じデータに対して読み込みリクエストを実行する場合、書き込みリクエストが完了した後で読み込みリクエストが実行されないと、書き込まれたデータを再度正確に読み込んでいるかどうかは保証されなくなります。

呼び出しがディスク切り替えダイアログを表示して、オフラインになっているボリュームをもう一度オンラインに戻すことで、リクエストの順序を変更することもできます。

ボリュームパラメータバリアントのオフセットは 2 ずつ増加する

2-293 ページ、アセンブリ言語の概要、データ構造体

ioVAlBlkSiz はワードではなくロングであるため、ボリュームパラメータバリアントのオフセットは ioVClpSiz を起点にして 2 ずつ増加していきます。その結果、ioVClpSiz のオフセットは 52 でなければならず、ioAlBlSt のオフセットは 56 でなければなりません。

ボリュームが MFS (Macintosh File System)、HFS (Hierarchical File System)、または HFS Plus でフォーマットされているかどうかの判定

これまで Mac OS ファイルシステムでは、MFS、HFS、HFS Plus という 3 つのボリュームフォーマットがサポートされてきました。System ソフトウェア 7.0 から Mac OS 8.0 では、MFS および HFS ボリュームフォーマットがサポートされていました。Mac OS 8.1 およびそれ以降では、HFS および HFS Plus ボリュームがサポートされています。これら 3 つのボリュームフォーマットでは、ローカルファイルシステム ID としてゼロ (0) を使用します。では、どのようにしてこれら 3 つのボリュームフォーマットを識別すればいいのでしょうか。このためには、PBXGetVolInfo (PBXGetVolInfo が使用できない場合は PBHGetVInfo) によって ioVSigWord フィールドに返されるボリュームのシグネチャワードを使用します。MFS ボリュームは $D2D7 というシグネチャを持ち、HFS ボリュームは $4244 というシグネチャを持ちます。また、HFS Plus ボリュームのシグネチャは $482B です。

重要
一部のプログラムとの互換性を維持するため、HFS および HFS Plus ボリュームの両方に対して PBGetVInfoPBHGetVInfo$4244 という値を ioVSigWord に返します。このため、可能な場合は必ず PBXGetVolInfo を使用してください。

次のコードはボリュームシグネチャとファイルシステム ID を取得するために使用できます。


 OSErr GetVSigWord(short vRefNum, short *vSigWord, short *fsid)
 {
    OSErr         result;
    long          response;
    XVolumeParam  pb;

    pb.ioVRefNum = vRefNum;
    pb.ioXVersion = 0;      // この XVolumeParam のバージョン (0)
    pb.ioNamePtr = NULL;
    pb.ioVolIndex = 0;      // ioVRefNum のみを使用
    // PBXGetVolInfo は使用できるか
    if ( ( Gestalt(gestaltFSAttr, &response) == noErr ) &&
         ((response & (1L << gestaltFSSupports2TBVols)) != 0) )
    {
       // Yes なら使用する
       result = PBXGetVolInfoSync(&pb);
    }
    else
    {
       // No なら、PBHGetVInfo に戻る
       result = PBHGetVInfoSync((HParmBlkPtr)&pb);
    }
    // ボリュームのシグネチャと FSID を返す
    *vSigWord = pb.ioVSigWord;
    *fsid = pb.ioVFSID;
    // File Manager の結果を返す
    return ( result );
 }

PBXGetVolInfo

PBXGetVolInfo 関数を使用すると、ボリュームに関する詳細情報を取得することができます。最大 2 テラバイトまでのボリュームを対象にボリュームサイズ情報をレポートすることができます。

pascal OSErr PBXGetVolInfoSync(XVolumeParamPtr paramBlock);
pascal OSErr PBXGetVolInfoAsync(XVolumeParamPtr paramBlock);

paramBlock 拡張ボリュームパラメータブロックへのポインタ。

XVolumeParam
->ioCompletionProcPtr完了ルーチンへのポインタ。
<-ioResultOSErr関数の結果コード。
<->ioNamePtrStringPtrボリュームの名前へのポインタ。
<->ioVRefNumshort入力時はボリューム仕様、出力時はボリューム参照番号。
->ioXVersionunsigned longXVolumeParam のバージョン (value = 0)。
->ioVolIndexshortマウントされているすべてのボリュームを指定するために使用するインデックス。
<-ioVCrDateunsigned long初期化の日付と時刻。
<-ioVLsModunsigned long最終修正の日付と時刻。
<-ioVAtrbshortボリューム属性。
<-ioVNmFlsunsigned shortルートディレクトリにあるファイルの数。
<-ioVBitMapunsigned shortボリュームビットマップの先頭ブロック。
<-ioVAllocPtrunsigned short次の新規ファイルが始まるブロック。
<-ioVNmAlBlksunsigned shortアロケーションブロックの数。
<-ioVAlBlkSizunsigned longアロケーションブロックのサイズ。
<-ioVClpSizunsigned longデフォルトのクランプサイズ。
<-ioAlBlStunsigned shortボリュームブロックマップの先頭ブロック。
<-ioVNxtCNIDunsigned long次の未使用カタログノード ID。
<-ioVFrBlkunsigned short未使用アロケーションブロックの数。
<-ioVSigWordunsigned shortボリュームシグネチャ。
<-ioVDrvInfoshortドライブ番号。
<-ioVDRefNumshortドライバ参照番号。
<-ioVFSIDshortこのボリュームを処理するファイルシステムのファイルシステムID。
<-ioVBkUpunsigned long最終バックアップの日付と時刻。
<-ioVSeqNumshort内部的に使用されます。
<-ioVWrCntunsigned longボリューム書き込みカウント。
<-ioVFilCntunsigned longボリューム上にあるファイルの数。
<-ioVDirCntunsigned longボリューム上にあるディレクトリの数。
<-ioVFndrInfo[8] longFinderによって使用されます。
<-ioVTotalBytesUnsignedWideボリューム上にある総バイト数。
<-ioVFreeBytesUnsignedWideボリューム上にある空きバイト数。

PBXGetVolInfo 関数は指定されたボリュームに関する情報を返します。この関数は、『Inside Macintosh: Files』で説明されている PBHGetVInfo 関数に類似していますが、追加のボリューム領域情報を 64 ビット整数として返し、ボリュームの VCB (Volume Control Block) からコピーした情報を修正しない点が異なります。PBXGetVolInfo をサポートするシステムでは、gestaltFSAttr Gestalt セレクタの戻り値に応答して gestaltFSSupports2TBVols ビットがセットされます。

アセンブリ言語の情報

PBXGetVolInfo に対応したトラップマクロおよびルーチンセレクタは以下のとおりです。

トラップマクロセレクタ
_HFSDispatch$0012

結果コード

noErr0関数は正常に実行され、エラーは発生していません。
nsvErr-35そのようなボリュームは存在しません。
paramErr-50デフォルトボリュームは存在しません。

PBGetXCatInfo

PBGetXCatInfo 関数を使用すると、ファイルとディレクトリに対する短い名前 (MS-DOS 形式の名前) と ProDOS 情報を取得することができます。

pascal OSErr PBGetXCatInfoSync(XCInfoPBPtr paramBlock);
pascal OSErr PBGetXCatInfoAsync(XCInfoPBPtr paramBlock);

paramBlock XCInfoPBRec へのポインタを含みます。

XCInfoPBRec
->ioCompletionProcPtrPBGetXCatInfoAsync の完了ルーチンへのポインタを含みます。
<-ioResultOSErrPBGetXCatInfo はその結果コードをこのフィールドに格納します。
->ioNamePtrStringPtrオブジェクト名へのポインタを含みます。また、ioDirID がオブジェクトであるディレクトリを指定するときは nil。
->ioVRefNumshortボリューム仕様を含みます。
<->ioShortNamePtrStringPtrPascal 文字列バッファ (最小 13 バイト) へのポインタを含みます。PBGetXCatInfo は短い名前をこのパラメータによって参照されるフィールドに格納します。ioShortNamePtr が nil になることはありません。
<-ioPDTypeshortPBGetXCatInfoProDOS ファイルのタイプをこのフィールドに格納します。
<-ioPDAuxTypelongPBGetXCatInfoProDOS 補助タイプをこのフィールドに格納します。
->ioDirIDlongディレクトリ ID を含むます。

PBGetXCatInfo 関数は、この関数をサポートするボリューム上のファイルとディレクトリに対する短い名前 (MS-DOS 形式の名前) と ProDOS ファイル/補助タイプ情報を返します。PBGetXCatInfo をサポートするボリュームでは、PBHGetVolParms から返された vMAttrib フィールドで bHasShortName ビットがセットされます。

短い名前と ProDOS ファイル/補助タイプの詳細については、『Inside AppleTalk, second edition』の第 13 章を参照してください。

アセンブリ言語の情報

PBGetXCatInfo にするトラップマクロおよびルーチンセレクタは以下のとおりです。

トラップマクロセレクタ
_HFSDispatch$003A

結果コード

noErr0関数は正常に実行され、エラーは発生していません。
nsvErr-35そのようなボリュームは存在しません。
fnfErr-43ファイルが見つかりません。
paramErr-50デフォルトボリュームは存在しません。
dirNFErr-120ディレクトリが見つかりません。

先頭ページに戻る


第 3 章 - 標準ファイルパッケージ

アクティベーションプロシージャでは TECalText を呼び出す必要がある

3-30 ページから 3-31 ページ、アクティベーションプロシージャの書き方
3-59 ページ、MyActivateProc

3-30 ページから 3-31 ページ、および 3-59 ページでは、カスタム標準ファイルダイアログに追加したユーザインタフェース要素をアクティブにする方法を説明しています。しかし、複数のテキスト編集項目の追加に関連する箇所で言及すべき内容が省略されています。以下のコードに示すように、アクティベーションプロシージャを正常に動作させるためには、TECalText を呼び出し、myTEHandle^^.crOnly に 1 を設定し、さらに TESetSelect を呼び出す必要があります。


 IF (activating) THEN
     BEGIN
         {WindowPeek ではなく DialogPeek を使用する点に注意}
         dlgPeek := DialogPeek(theDialog);

         {ダイアログ内のすべての editText 項目によって共有される TEHandle にアクセスする}
         {このフィールドはアクティベーション時にカレントフィールドになる}
         myTEHandle:= dlgPeek^.textH;

         {アクティベーション時に lineStarts をやり直す必要がある}
         TECalText(myTEHandle);

         {アクティベーション時に crOnly を設定する必要がある}
         myTEHandle^^.crOnly := 1;

         {選択の設定が適切であることを確認する}
         myTECharLength := myTEHandle^^.teLength;
         selectionLen := myTEHandle^^.selEnd - myTEHandle^^.selStart
                         + 1;
         If (myTECharLength > selectionLen) THEN
         TESetSelect(0,myTECharLength,myTEHandle);
     END;

デフォルトの標準ファイルカレントディレクトリ

3-31 ページ、カレントディレクトリの設定

2 つある箇条書きの項目を次の 3 つの項目に置き換えてください。

  • ユーザがアプリケーションを直接的に起動する場合 (おそらくは Finder でそのアイコンをダブルクリックして)、アプリケーションが格納されているディレクトリがデフォルトディレクトリになります。

  • ユーザがアプリケーションを間接的に起動し (おそらくはそのアプリケーションで作成した書類のアイコンをダブルクリックして)、そのアプリケーションがハイレベルイベントを認識できる場合、アプリケーションには、オープンまたは印刷を行うために kAEOpenDocument または kAEPrintDocument Apple イベントに含まれている書類のリストが渡されます。このとき、Finder 情報は存在せず (AppParmHandle は NIL になります)、アプリケーションが格納されているディレクトリがデフォルトディレクトリになります。

  • ユーザがアプリケーションを間接的に起動し (おそらくはそのアプリケーションで作成した書類のアイコンをダブルクリックして)、そのアプリケーションがハイレベルイベントを認識できない場合、アプリケーションには Finder 情報が渡され、Finder 情報の最後にリストされている書類のディレクトリがデフォルトディレクトリになります。Finder 情報は、AppParmHandle によって参照され、セグメントローダルーチンの CountAppFiles、GetAppFiles、ClrAppFiles、および GetAppParms によってアクセスされるデータです。

リスト 3-15 では sfScript フィールドを設定していない

3-33 ページ、リスト 3-15、カレントディレクトリの設定

コードのリストでは、疑似項目 sfHookChangeSelection が返されるときに StandardFileReply レコードの sfScript フィールドを設定していません。これにより、標準ファイルは常にディレクトリ内の最後のファイルを選択するように設定されてしまいます。次の行を

 myReplyPtr^.sfScript := smSystemScript;

次の行の前に追加すると、問題が解決されます。

 MyDlgHook := sfHookChangeSelection;

先頭ページに戻る


第 4 章 - Alias Manager

ResolveAlias はミニマルエイリアスを更新する

4-19 ページ

4-19 ページの最後に、「ResolveAlias はミニマルエイリアスを更新しません」と記載されていますが、これは正しくありません。

ResolveAliasMatchAlias を呼び出してエイリアスを解決し、MatchAlias が true に設定された needsUpdate を返す場合は、UpdateAlias (フルエイリアスを作成する) を呼び出してエイリアスを更新し、true に設定された wasChanged を返します。ミニマルエイリアスをそのままにしておく必要がある場合は、MatchAlias (エイリアスを更新しない) を呼び出すことができます。または、HandToHand を使ってエイリアスレコードのコピーを作成し、エイリアスレコードのコピーを ResolveAlias に渡した後、(おそらくは更新されている) エイリアスレコードのコピーを破棄することができます。

usrCanceledErruserCanceledErr でなければならない

4-20 ページ、ResolveAlias 4-23, MatchAlias

単純な誤植です。

kARMSearchMore と、AliasFilterProc で使用可能なメモリの警告

4-23 ページ、MatchAlias
4-25 ページ、MyMatchAliasFilter

次の警告を追加してください。

警告
kARMSearchMore 規則を使った MatchAlias の呼び出しは、検索されるボリュームが PBCatSearch をサポートしていないと、結果的に PBGetCatInfo を使って再帰的な検索を行うことになります。このためアプリケーションでは、kARMSearchMore 規則を使った MatchAlias を呼び出す前に、使用可能な十分な量のスタック領域が存在することを確認してください。また、AliasFilterProc が使用されている場合は、AliasFilterProc が大量のスタック領域を使用しないように注意してください。AliasFilterProcyourDataPtr パラメータで必要とする可能性のあるサイズの大きなデータ構造体を含む構造を MatchAlias に渡すことで、AliasFilterProc による大量のスタック消費を抑えることができます。

先頭ページに戻る


第 5 章 - Disk Initialization Manager

拡張ディスク初期化パッケージ

拡張ディスク初期化パッケージは、System ソフトウェア 7.5 またはそれ以降、Macintosh PC Exchange 2.0 またはそれ以降、および File System Manager とともに使用することができます。拡張ディスク初期化パッケージには、『Inside Macintosh: Files』の第 5 章で説明されていない 3 つの関数が含まれます。

『Inside Macintosh: Files』で説明されているように、ディスク初期化パッケージへの既存のアプリケーションプログラムインタフェースは、拡張ディスク初期化パッケージでも引き続きサポートされています。Macintosh ディスクのみを初期化しようとするアプリケーションは今後もこれまで同様に動作するため、何らかの変更を加える必要はありません。しかし、アプリケーションが非 Macintosh ディスクを初期化する場合は、新しく拡張された DIXFormat および DIXZero 呼び出しを使用する必要があります。

拡張ディスク初期化ユーザインタフェース

Finder と標準ファイルパッケージの両方は、ユーザにディスクのイジェクトと初期化のどちらを行うかを確認するディスク初期化ダイアログボックスを表示することで、初期化されていないディスクに対するディスク挿入イベントを処理します。ユーザが無効なディスクを挿入したときには、アプリケーションでもこのようなダイアログボックスを表示する Disk Initialization Manager ルーチンを簡単に呼び出すことができます。図 5-1 に、このダイアログボックスの具体例を示します。

図 5-1 ディスク初期化ダイアログボックス



ディスク初期化ダイアログボックスを使用すると、ユーザは新しいディスクの名前とフォーマットを指定できます。ディスク初期化ダイアログボックスのアピアランスは条件の変更を反映して変化します。たとえば、ディスクが含まれているドライブを示すためアイコンが変化します。「フォーマット」メニューの項目は、現在のディスクとディスクドライブの組み合わせで使用できるディスクフォーマットを示すために変化します。また、ダイアログボックスに表示されるテキストはディスクに発生した問題にしたがって変化します。現在のディスクドライブでは挿入されたディスクのフォーマットを使用できない (たとえば、片面ドライブに両面ディスクを挿入した場合や、MFM ではなく GCR を使ってフォーマットした高密度ディスクを Apple SuperDrive に挿入した場合など) ということを Disk Initialization Manager が検出すると、「このディスクのフォーマットはこのドライブでは読み取れません」といった内容のテキストが表示されます。

最初に表示されたときのアピアランスに関係なく、ユーザが「イジェクト」または「キャンセル」ボタンをクリックすると、ディスク初期化ダイアログボックスは画面が消えます。しかし、ユーザがディスクの初期化を選択すると、図5-2に示すように、ダイアログボックスのテキストが変わり、初期化によってディスク上の既存のデータがすべて消去されることをユーザに警告します。

図 5-2 ディスク初期化の警告



ユーザが継続を選択すると、Disk Initialization Manager はディスクの初期化を試みます。何らかのエラーが発生して初期化に失敗すると、そのことをユーザに通知するアラートボックスが表示され、ディスクが自動的にイジェクトされます。

拡張 Disk Initialization Manager は、標準インタフェースを使って、すでにフォーマットされているディスクを再初期化 (再フォーマット) するためのメカニズムも提供します (このメカニズムはディスクを異なるディスクフォーマットを使って再初期化する必要があるときなどに役立ちます)。図 5-3 に示すように、Finder は「ディスクの初期化」コマンドを使って、このメカニズムを利用します。このダイアログボックスでユーザが消去操作を選択すると、警告を表示することなく、即座に再初期化が開始されます。必要な場合は、アプリケーションでもこれと同じ標準インタフェースを使って、ユーザにマウントされているディスク (スタートアップボリューム以外の) を再初期化させることができます。また、ダイアログボックスに表示されるテキストをカスタマイズすることもできます。なお、実際にユーザにこの機能を提供する必要があるのは、ごく一部のユーティリティアプリケーションのみです。

図 5-3 再フォーマットダイアログボックス



ディスクコピーアプリケーションのようなユーティリティプログラムを開発している場合は、標準ディスク初期化ダイアログボックスを表示することなく、新しいディスクの初期化や既存の有効なディスクの再初期化を行わなければならないこともあります。たとえば、ユーザがその都度、標準ダイアログボックスに応答するのではなく、一度に複数のディスクを初期化するような場合です。Disk Initialization Manager は、このような処理を可能にするローレベルのルーチンを提供します。この種のユーティリティプログラムを開発するのでなければ、これらのルーチンを使用する必要はありません。

拡張ローレベルディスク初期化ルーチン

メディアフォーマットおよびボリューム初期化関数への拡張プログラムインタフェースでは、前述のようなアプリケーションがフォーマット操作全体に対する追加情報を指定することを要求します。この情報は、ディスク初期化ダイアログボックスの「フォーマット」メニューに表示されるファイルシステムのタイプとディスクサイズの情報に対応します。拡張プログラムインタフェースは、DIXFormat、DIXZero (DIFormat と DIZero の拡張バージョン)、および DIReformat という3つの新しい関数をディスク初期化パッケージに追加します。

警告
アプリケーションでは、DIXFormat、DIXZero、または DIReformat を呼び出す前に、ディスク初期化パッケージ関数が存在することを確認してください。これを行うには、gestaltFSAttr セレクタを使った Gestalt を呼び出します。Gestalt 関数が戻り値として noErr を返し、応答パラメータで gestaltHasExtendedDiskInitbit (ビット 6) がセットされていれば、拡張ディスク初期化パッケージ関数を使用することができます。ディスク初期化パッケージの以前のバージョンの仕様により、拡張リクエストが使用できないときにそれを無理に呼び出そうとすると、システムクラッシュの原因になります。

次のコードは、拡張ディスク初期化パッケージ関数が使用可能であるかどうかを判定する Gestalt 関数の使い方を具体的に示しています。


 Boolean  HasExtendedDIFunctions(void)
 {
    long response;

    if (Gestalt(gestaltFSAttr, &response) == noErr)
       return ((response & (1L << gestaltHasExtendedDiskInit)) != 0);
    else
       return (false);
 }

DIXFormat

DIXFormat 関数は DIFormat 関数と同じ機能を実行しますが、ドライブサイズを指定する点が異なります。

pascal OSErr DIXFormat(short drvNum, Boolean fmtFlag,
                       unsigned long fmtArg, unsigned long *actSize);

drvNumフォーマットするドライブのドライバ番号を含みます。
fmtFlagfmtArg パラメータの意味を指定する論理値を含みます。
fmtArgfmtFlag が true の場合、fmtArg は、ディスクメディアを初期化するために "フォーマット" _Control 呼び出しが行われるときに、パラメータブロックの csParam フィールドとしてディスクドライバに渡される実際の値を指定します (この値はサイズリスト内のインデックスです。このパラメータに設定できる適切な値の説明については、テクニカルノートの「What Your Sony Drives For You」を参照してください)。

fmtFlag が false の場合、fmtArg は 512 バイトブロックの数として望ましいメディアのサイズを指定します。要求したサイズに一致するサイズと値を取得するためにディスクドライバが呼び出されます。同じサイズに対して複数のサイズリストエントリが存在する場合、fmtArg パラメータに最もよく一致するドライバによって返されたリスト内の先頭のエントリが使用されます。サイズリストの詳細については、テクニカルノートの「What Your Sony Drives For You」を参照してください。指定したサイズがドライバから返されたサイズリストの最大サイズよりも大きい場合は、その最大サイズが使用され、そのサイズが actSize に返されます。指定したサイズがドライバから返されたサイズリストの最小サイズよりも小さい場合は、その最小サイズが使用され、そのサイズは actSize に返されます。指定したサイズが最大サイズと最小サイズの間にあり、しかも完全に一致するサイズがない場合は、要求したサイズを超えない最も近い値が使用されます。
actSize符号なし long 整数へのポインタを含みます。正常なフォーマット操作が完了した時点で、DIXFormat はフォーマットされたメディアの実際のサイズを 512 バイトブロックの数として、このパラメータによって参照されるフィールドに格納します。

特殊なメディアフォーマットを必要とするファイルシステムのフォーマットを行うには、ディスクサイズのカウントだけでなく、それらのメディアフォーマットを明示的に指定する必要があります。特殊なメディア要件を含む外部ファイルシステムでは、サイズリストに含まれるドライバ固有の情報を使用するか、"サイズリストを評価する" ために呼び出しを行うときに、追加情報に対する適切なドライバ _Status 呼び出しを行う必要があります。

DIFormat と同様、DIXFormat はボリュームをアンマウントしません。この呼び出しを実行する前に、ボリュームをアンマウントしておく必要があります。ボリュームがアンマウントされていないと、DIXFormatvolOnLinErr エラーを返します。

結果コード

noErr0正常終了。
volOnLinErr-55ボリュームがオンラインになっています。
lastDskErr...firstDskErr-64...-84ローレベルディスクエラーの範囲。

DIXZero

DIXZero 関数は DIZero 関数と同じ機能を実行しますが、ファイルシステム、フォーマットの結果、ボリュームタイプ、ボリュームサイズ、および拡張フォーマット情報を指定する点が異なります。


pascal OSErr DIXZero(short drvNum, ConstStr255Param volName,
                     short fsid, short mediaStatus,
                     short volTypeSelector, unsigned long volSize,
                     void *extendedInfoPtr);

drvNum初期化するドライブのドライバ番号を含みます。
volNameボリュームの名前を指定する Pascal 文字列へのポインタを含みます。
fsidフォーマットがディスクに書き込まれるファイルシステムの ID を含みます。ファイルシステム ID は、File System Manager の GetFSInfo 関数を使って取得することができます。
mediaStatusディスクメディアのステータスを示すフラグを含みます。その値は DIVerify 関数から返された結果コードです。mediaStatus がゼロでないと、ディスクには不良セクタが含まれ、スペアリングの必要があります。指定されたファイルシステムで不良ブロックのスペアリングがサポートされていない場合、ディスク初期化パッケージは関数の実行結果として単純にこの値だけを返します。また、ファイルシステムで不良ブロックのスペアリングがサポートされている場合は、デフェクトリストが収集され、それがファイルシステムに渡されます。
volTypeSelector外部ファイルシステムで複数のボリュームタイプがサポートされている場合に使用するボリュームタイプセレクタを含みます。
volSizedrvNum で指定されたドライブの 512 バイトブロック単位のサイズを含みます。これは、DIXFormat によって actSize フィールドに返されたサイズ、つまり指定されたドライブ上のファイルシステムが使用できる領域の容量です。指定したサイズが現在のディスクフォーマットサイズと一致しない場合、DIXZerodiCIVolSizeMismatchErr を返します。
fsParams外部ファイルシステムの拡張フォーマット情報へのポインタ、または nil を含みます。

警告
DIXZero コードの初期バーションは、mediaStatus パラメータに渡された値が noErr でないとき、nil の DialogPtr を含む Dialog Manager を呼び出します。これにより、たいていの場合はシステムクラッシュが発生することになります。

mediaStatus パラメータとして noErr 以外の値を渡す前に、DIXZero が不良ブロックのスペアリングをサポートしていることを確認する必要があります。次の DIXZeroSupportsBadBlocks 関数は、DIXZero が不良ブロックのスペアリングをサポートしているかどうかを確認する方法を示しています。


 Boolean  DIXZeroSupportsBadBlocks(void)
 {
    enum
    {
       gestaltBugFixAttrsThree = 'bugx',
       gestaltDIXZeroSupportsBadBlocks = 9
    };
    long response;

    if (Gestalt(gestaltBugFixAttrsThree , &response) == noErr)
       return ((response & (1L << gestaltDIXZeroSupportsBadBlocks))
               != 0);
    else
       return (false);
 }

DIZero と同様、DIXZero はボリュームをアンマウントしませんが、操作が正常に終了した場合にボリュームをマウントします。この呼び出しを実行する前に、ボリュームをアンマウントしておく必要があります。DIZero または DIXZero を呼び出したときにボリュームがマウントされていると、volOnLinErr エラーが返されます。

結果コード

noErr0正常終了。
diCIVolSizeMismatchErr24指定したボリュームサイズはフォーマットされているディスクサイズと一致しません。
ioErr-36I/Oエラー。
paramErr-50指定したドライブ番号が不正です。
volOnLinErr-55ボリュームはすでにオンラインになっています。
nsDrvErr-56そのようなドライブは存在しません。
firstDskErr...lastDskErr-84...-64ローレベルディスクエラーの範囲。
memFullErr-108メモリ不足。

DIReformat

DIReformat 関数はディスクボリュームを再フォーマットします。


pascal OSErr DIReformat(short drvNum, short fsid,
                        ConstStr255Param volName,
                        ConstStr255Param msgText);

drvNumフォーマットするドライブのドライバ番号を含みます。
fsidフォーマットがディスクに書き込まれるファイルシステムの ID を含みます。ファイルシステム ID は、File System Manager の GetFSInfo 関数を使って取得することができます (Macintosh HFS ボリュームフォーマットの場合は $0000 を使用します)。
volNameボリュームの名前を指定する Pascal 文字列へのポインタを含みます。
msgTextディスク初期化ダイアログボックスに表示される説明テキストを指定する Pascal 文字列へのポインタを含みます。

これまでディスクの再フォーマットは、evtMessage パラメータの上位ワードに noErr を設定した DIBadMount 関数を呼び出すことで実現され、説明テキストは ParamText 関数を使って設定していました。DIReformat 関数は、説明テキスト、デフォルトのファイルシステム ID、および再フォーマットされたディスクのデフォルトの名前を指定する機能を呼び出し元に提供します。

注意
drvNum で指定されたドライブ内のボリュームは、DIReformat を呼び出す前にマウントされている必要があります。

結果コード

noErr0正常終了。
diCINoMessageTextErr28msgTextが指定されていません。
ioErr-36I/Oエラー。
paramErr-50指定したドライブ番号が不正です。
nsDrvErr-56そのようなドライブは存在しません。
firstDskErr...lastDskErr-84...-64ローレベルディスクエラーの範囲。
memFullErr-108メモリ不足。

HFS および HFS Plus ボリュームのフォーマット

ディスク初期化パッケージは、プログラムがファイルシステムによって使用されるディスクドライブを初期化するための方法を提供します。ドライブがマウントされているファイルシステムボリュームでない場合、プログラムは DIBadMount を呼び出して、ディスク初期化パッケージにディスク初期化ダイアログボックスを使ったユーザインタフェースを提供させることができます (「拡張ディスク初期化ユーザインタフェース」を参照してください)。ドライブがすでにフォーマットされていて、ファイルシステムによってマウントされている場合、プログラムは DIReformat を呼び出して、ディスク初期化パッケージに再フォーマットダイアログボックスをユーザインタフェースを提供させることができます。プログラムがユーザインタフェースなしにボリュームのデータ構造を初期化または再初期化する必要がある場合は、DIZero または DIXZero を使用することができます。DIZero は常にディスクを HFS ボリュームとしてフォーマットします。ディスクを HFS Plus ボリュームとして初期化したい場合、または外部ファイルシステムで使用するためにディスクを初期化したい場合は、DIXZero を使用する必要があります。このセクションでは、DIXZero を使って、ディスクを HFS または HFS Plus ボリュームとして初期化する方法について説明します。

fsid パラメータは、ボリュームの初期化に使用するファイルシステムを DIXZero に指示します。HFS および HFS Plus ボリュームの場合は fsid パラメータとして $0000 を渡します (ローカルファイルシステムのファイルシステム ID)。

volTypeSelector パラメータは、単一のファイルシステムによってサポートされている複数のボリュームタイプの中から目的のものを選択するために使用します。HFS ボリュームを作成するには、volTypeSelector パラメータとして 1 を渡し、HFS Plus ボリュームを作成するには、volTypeSelector パラメータとして 2 を渡します。

extendedInfoPtr パラメータは、ボリュームをフォーマットする方法を調整する省略可能な構造体へのポインタです。HFS ボリュームをフォーマットするとき、このパラメータは HFSDefaults 型の構造体をポイントする必要があり、HFS Plus ボリュームの場合は HFSPlusDefaults 型の構造体をポイントする必要があります。extendedInfoPtr パラメータとして NIL を渡すと、ファイルシステムのデフォルト値が使用されることになります。

HFSDefaults


 struct HFSDefaults {
   char   sigWord[2];  /* シグネチャワード */
   long   abSize;      /* バイト単位のアロケーションブロックサイズ */
   long   clpSize;     /* バイト単位のクランプサイズ */
   long   nxFreeFN;    /* 次の空きファイル番号 */
   long   btClpSize;   /* バイト単位の B ツリークランプサイズ */
   short  rsrv1;       /* 予約済み */
   short  rsrv2;       /* 予約済み */
   short  rsrv3;       /* 予約済み */
 };
 typedef struct HFSDefaults HFSDefaults;

HFSDefaults 構造体を使用すると、HFS ボリュームをフォーマットするときに使用されるいくつかのパラメータを変更することができます。それぞれのフィールドにゼロまたは無効な値を設定すると、デフォルト値の使用を指定したことになります。

sigWord にはバイト $4244 ('BD') を設定します。

abSize フィールドはボリュームのアロケーションブロックサイズを設定します。この値は 512 バイトの倍数でなければなりません。アロケーションブロックサイズのデフォルト値と最小値は、512 の倍数の中で、ボリュームサイズ (バイト単位) を 65535 ($FFFF) で割った値以上の最小の値です。

clpSize フィールドはボリュームのデフォルトクランプサイズを設定します。この値は、ファイルを拡張するために領域を割り当てるときに使用されます。十分な空き領域が使用可能な場合、割り当てられた領域はクランプサイズの倍数に切り上げられます。クランプサイズはアロケーションブロックサイズの倍数でなければなりません。アロケーションブロックサイズが 256K またはそれ以下の場合は、アロケーションブロックサイズの 4 倍がデフォルト値になります。また、アロケーションブロックサイズがそれよりも大きいと、デフォルト値はアロケーションブロックサイズに等しくなります。

nxFreeFN フィールドは MDB の drNxtCNID フィールドを設定します。これは、そのボリューム上のファイルとフォルダに割り当てられるカタログノード ID の開始値に相当します。この値は実際には符号なし 32 ビット整数です。デフォルト値と最小値は fsUsrCNID (16)、つまりユーザファイルとフォルダに対する有効な最小のカタログノード ID です。

btClpSize フィールドはクランプサイズと、カタログおよびエクステント B ツリーに割り当てられる領域の初期値の両方を設定します。クランプサイズはアロケーションブロックサイズの倍数でなければなりません。デフォルト値はボリュームサイズによって変わりますが、通常はボリュームサイズの 1/128 です。

HFSPlusDefaults


 enum {
   kHFSPlusDefaultsVersion = 1
 };

 struct HFSPlusDefaults {
   UInt16  version;             /* この構造体のバージョン */
   UInt16  flags;               /* 現在は未定義、ゼロを渡す */
   UInt32  blockSize;           /* バイト単位のアロケーションブロックサイズ */
   UInt32  rsrcClumpSize;       /* リソースフォークのクランプサイズ */
   UInt32  dataClumpSize;       /* データフォークのクランプサイズ */
   UInt32  nextFreeFileID;      /* 次の空きファイル番号 */
   UInt32  catalogClumpSize;    /* カタログ B ツリーのクランプサイズ */
   UInt32  catalogNodeSize;     /* カタログ B ツリーのノードサイズ */
   UInt32  extentsClumpSize;    /* エクステント B ツリーのクランプサイズ */
   UInt32  extentsNodeSize;     /* エクステント B ツリーのノードサイズ */
   UInt32  attributesClumpSize; /* アトリビュート B ツリーのクランプサイズ */
   UInt32  attributesNodeSize;  /* アトリビュート B ツリーのノードサイズ */
   UInt32  allocationClumpSize; /* アロケーションビットマップファイルのクランプサイズ */
 };
 typedef struct HFSPlusDefaults HFSPlusDefaults;

HFSPlusDefaults 構造体を使用すると、HFS Plus ボリュームをフォーマットするときに使用されるいくつかのパラメータを変更することができます。それぞれのフィールドにゼロまたは無効な値を設定すると、デフォルト値の使用を指定したことになります。

version フィールドは関数に渡す HFSPlusDefaults 構造体のバージョンを指定します。現在のバージョンは kHFSPlusDefaultsVersion です。渡した値が現在のインプリメンテーションによって認識される値を超えていると、paramErr が返されます。通常、インプリメンテーションは HFSPlusDefaults の古いバージョンをサポートします。

flags フィールドは現在予約されています。ゼロ以外の値を渡すと、paramErr が返されます。

blockSize フィールドはボリュームのアロケーションブロックサイズを設定します。有効な値は 512 以上となる 2 のべき乗値です。デフォルト値はボリュームのサイズによって変わります。256MB またはそれ以下のボリュームでは 512 バイトになり、1GB を超えるボリュームでは最大 4KB までの値を設定できます。ボリュームのデバイスが GetMediaInfo 制御呼び出しをサポートしている場合、デフォルトのサイズはデバイスのブロックサイズ以上の値になります。

注意
HFS Plus ファイルシステムの将来のバージョンでは、アロケーションブロックが 4KB のときにパフォーマンスが最適化される予定です。このため、特に理由がないかぎりデフォルト値を使用することをお勧めします。

rsrcClumpSize および dataClumpSize フィールドはそれぞれ、リソースフォークとデータフォークのクランプサイズのデフォルト値を設定します。この値はアロケーションブロックサイズの倍数でなければなりません。両方のフィールドのデフォルト値はアロケーションブロックサイズの 4 倍です。

nextFreeFileID フィールドは新しく作成されたファイルとフォルダに割り当てられる最初のカタログノード ID を設定します。デフォルト値と最小値は fsUsrCNID (16)、つまりユーザファイルとフォルダに対する有効な最小のカタログノード ID です。

catalogClumpSize および extentsClumpSize フィールドはそれぞれ、クランプサイズと、カタログおよびエクステント B ツリーに最初に割り当てる領域を設定します。両方のフィールドのデフォルト値はボリュームサイズによって変わりますが、通常はボリュームサイズの 1/128 です。

catalogNodeSize および extentsNodeSize フィールドはそれぞれ、カタログおよびエクステント B ツリーに対する B ツリーノードのサイズを設定します。有効な値は最大 32,768 (32K) までの 2 のべき乗値です。catalogNodeSize のデフォルト値と最小値は 4KB です。また、extentsNodeSize の最小値は 512 で、デフォルト値は 1024 です。

いくつかのサンプルコード

次のサンプルは、DIReformat を使って、標準インタフェースを使用するディスクを再初期化する方法を示しています。DIReformat が使用可能であるとき、このコードは『Inside Macintosh: Files』の 5-11 ページのリスト 5-2 に示されているコードの代用として使用できます。


 // 標準インタフェースを使用する有効なディスクを再初期化
 OSErr ReformatDisk(short drvNum, ConstStr255Param msgText)
 {
   OSErr  result;
   Str255  volName;
   short  vRefNum;
   long  freeBytes;

   DILoad();
   // 現在のボリューム名を取得
   result = GetVInfo(drvNum, volName, &vRefNum, &freeBytes);
   if ( result == noErr )
   {
     // FSID $0000 (HFS または HFS Plus) を使って再フォーマット
     result = DIReformat(drvNum, 0x0000, volName, msgText);
   }
   DIUnload();
   return ( result );
 }

次のサンプルは、DIXZero を使って、標準インタフェースを使用しないディスクを再初期化する方法を示しています。このサンプルでは、可能な場合に HFS Plus を使ってボリュームを初期化できるように DIXZero を使用しています。


 // 標準インタフェースを使用しない有効なディスクを再初期化
 OSErr ReinitializeDisk(short drvNum, Boolean tryHFSPlus)
 {
   OSErr  result;
   Str255  volName;
   short  vRefNum;
   long  freeBytes;
   short  mediaStatus;
   UInt32  actSize;

   DILoad();
   // 現在のボリューム名を取得
   result = GetVInfo(drvNum, volName, &vRefNum, &freeBytes);
   if ( result == noErr )
   {
     // ボリュームをアンマウント
     result = UnmountVol(NULL, vRefNum);
     if ( result == noErr )
     {
       // ディスクをフォーマット (注意: 実際のディスクサイズ)
       result = DIXFormat(drvNum, false, 0, &actSize);
       if ( result == noErr )
       {
         // ディスクを検証し、その結果を mediaStatus として使用
         mediaStatus = (short)DIVerify(drvNum);

         // HFS Plus フォーマットを使用するか
         if ( tryHFSPlus )
         {
           // Yes の場合は HFS Plus を使って初期化
           // (fsid = 0; volTypeSelector = 2)
           // extendedInfoPtr が NULL であるため、デフォルトのボリューム特性を使用
          result = DIXZero(drvNum, volName, 0x0000, mediaStatus, 2,
                    actSize, NULL);
         }

         // HFS Plus がリクエストされなかったり、ディスクが小さすぎるために HFS Plus を
         // 使った試みが失敗した場合 (paramErr)
         if ( !tryHFSPlus || (result == paramErr) )
         {
           // HFS を使って初期化 (fsid = 0; volTypeSelector = 1)
           // extendedInfoPtrがNULLであるため、デフォルトのボリューム特性を使用
           result = DIXZero(drvNum, volName, 0x0000, mediaStatus, 1,
                    actSize, NULL);
         }
       }
     }
   }
   DIUnload();
   return ( result );
 }

次のサンプルは、DIXZero を使って、標準インタフェースを使用しないディスクを初期化する方法を示しています。このサンプルでは、可能な場合に HFS Plus を使ってボリュームを初期化できるように DIXZero を使用しています。


 // 標準インタフェースを使用しない初期化されていないディスクを初期化
 OSErr InitializeDisk(short drvNum, ConstStr255Param volName,
                      Boolean tryHFSPlus)
 {
   OSErr  result;
   short  mediaStatus;
   UInt32  actSize;

   DILoad();
   // ディスクをフォーマット
   result = DIXFormat(drvNum, false, 0, &actSize);
   if ( result == noErr )
   {
     // ディスクを検証し、その結果を mediaStatus として使用
     mediaStatus = (short)DIVerify(drvNum);

     // HFS Plus フォーマットを使用するか
     if ( tryHFSPlus )
     {
       // Yes の場合は HFS Plus を使って初期化
       // (fsid = 0; volTypeSelector = 2)
       // extendedInfoPtr が NULL であるため、デフォルトのボリューム特性を使用
       result = DIXZero(drvNum, volName, 0x0000, mediaStatus, 2,
                actSize, NULL);
     }

     // HFS Plus がリクエストされなかったり、ディスクが小さすぎるために HFS Plus を
     // 使った試みが失敗した場合 (paramErr)
     if ( !tryHFSPlus || (result == paramErr) )
     {
       // HFS を使って初期化 (fsid = 0; volTypeSelector = 1)
       // extendedInfoPtr が NULLであるため、デフォルトのボリューム特性を使用
       result = DIXZero(drvNum, volName, 0x0000, mediaStatus, 1,
                actSize, NULL);
     }
   }
   DIUnload();
   return ( result );
 }

先頭ページに戻る


参考文献

先頭ページに戻る


ダウンロード

PDF このテクニカルノートの Acrobat ファイル (147K)

先頭ページに戻る


改訂の履歴

全般

  • このテクニカルノートの初版は 1995 年 2 月、「Technote 1041 - Inside Macintosh: Files Errata」として Jim Luther によって書かれました。

  • このテクニカルノートは 1995 年 6 月、初版以降に指摘された誤植を訂正して内容の不備を補うため、Jim Luther によって更新されました。

  • このテクニカルノートは 1996 年 2 月、前回の改訂以降に指摘された誤植を訂正して内容の不備を補うため、Jim Luther と Pete Gontier によって更新されました。

  • このテクニカルノートは 1999 年 2 月、HFS Plus の追加情報を組み込むため、Jim Luther によって全面的な改訂と更新が加えられました。

個別の項目

第 1 章 - File Management の概要

  • FSpExchangeFiles と PBExchangeFiles - 何が交換されるか、1995 年 2 月
  • GetVInfo に関する追加検討事項、1995 年 2 月
第 2 章 - File Manager
  • パス名の規則が完全に説明されていない、1995 年 2 月
  • 表 2-10 に記載されていない行がある、1995 年 2 月
  • 起動時のデフォルトディレクトリの説明に不備がある、1996 年 2 月
  • マスターディレクトリブロックの drXTFlSize および drCTFlSize フィールドの説明に不備がある、1995 年 2 月
  • マップノードのマップレコードは492バイト (494バイトではなく) を占有する、1995年2月
  • vcbAtrb のボリュームキャッシュコントロールビット、1995 年 6 月
  • ボリュームコントロールブロックの vcbXTAlBks および vcbCTAlBks フィールドの説明に不備がある、1995 年 6 月
  • 3.5 インチフロッピーディスク上では使用されない dQDrvSiz フィールド、1996 年 2 月
  • ParamBlockRec、HParamBlockRec、および CInfoPBRec の ioFlAttribビット の明確化、1995 年 6 月
  • ioACUser はいくつかのインタフェースファイルの中では filler2 になっている、1995 年 6 月
  • VolMountInfoHeader データ構造体にはフラグワードが含まれている、1995 年 2 月
  • PBRead および PBWrite リクエストによる ioPosMode の使い方、1995 年 6 月
  • GetVInfo に関する追加検討事項、1995 年 2 月
  • PBHGetVInfo に関して特に検討すべき問題、1995 年 2 月
  • FSpGetFInfo はディレクトリとともに動作しない、1995 年 2 月
  • FSpSetFInfo はディレクトリとともに動作しない、1995 年 2 月
  • HOpenDF、PBHOpenDF、および paramErr 結果コード、1995 年 2 月
  • パラメータブロックに ioFVersNum フィールドがない、1995 年 2 月
  • パラメータブロックに ioMisc フィールドがない、1995 年 2 月
  • PBGetCatInfo の ioFDirIndex の使用規則、1995 年 2 月
  • パラメータブロックに ioNamePtr フィールドがない、1995 年 2 月
  • ioForeignPrivIDirID は PBGetForeignPrivs と PBSetForeignPrivs では LongInt である、1995 年 2 月
  • リクエストの実行順序、1995 年 2 月
  • ボリュームパラメータバリアントのオフセットは 2 つずつ増加する、1995 年 2 月
  • ボリュームが MFS (Macintosh File System)、HFS (Hierarchical File System)、または HFS Plus でフォーマットされているかどうかの判定、1999 年 2 月
  • PBXGetVolInfo、1999 年 2 月
  • PBGetXCatInfo、1999 年 2 月
第 3 章 - 標準ファイルパッケージ
  • アクティベーションプロシージャでは TECalText を呼び出す必要がある、1995 年 2 月
  • デフォルトの標準ファイルカレントディレクトリ、1995 年 2 月
  • リスト 3-15 では sfScript フィールドを設定していない、1995 年 2 月
第 4 章 - Alias Manager
  • ResolveAlias はミニマルエイリアスを更新する、1995 年 2 月
  • usrCanceledErr は userCanceledErr でなければならない、1995 年 2 月
  • kARMSearchMore と、AliasFilterProc で使用可能なメモリの警告、1995 年 2 月
第 5 章 - Disk Initialization Manager
  • 拡張ディスク初期化パッケージ、1995 年 2 月
  • 拡張ディスク初期化ユーザインタフェース、1999 年 2 月
  • 拡張ローレベルディスク初期化ルーチン、1999 年 2 月
  • DIXFormat、1999 年 2 月
  • DIXZero、1999 年 2 月
  • DIReformat、1999 年 2 月
  • HFS および HFS Plus ボリュームのフォーマット、1999 年 2 月