Technote 1106
Update: Borrowed AFP Sessions
目次
はじめに
サーバボリューム情報ステータスコール
まとめ |
Macintosh ファイルシステムにマウントされた
AFP ボリュームのセッション・リファレンス番号の借用方法を説明します。マウントされた
AFP ボリュームのファイルシステムの情報を取得する方法も説明します。
この TECHNOTE は、AFP セッションの借用に関する以前の TECHNOTE の改版で、AppleShare
Client 3.7 以降を使用するシステムに該当します。それ以前のバージョンの AppleShare
Client については『Technote NW 16』に記載されている情報にしたがってください。 |
*更新箇所は太字および斜体で示します。
はじめに
AppleShare Chooser Extension は、File Manager コマンドを、そのコマンドと等価な
AFP コマンドに変換するため、Macintosh アプリケーションは、AppleTalk Filing Protocol
(AFP) ファイルサーバに対して、ほとんどすべてのボリューム/ファイルアクセス操作を行うことができます。アプリケーションは通常、ファイルサーバにアクセスするのに
File Manager を呼び出します。File Manager は、AppleShare エクスターナル・ファイルシステム
(AppleShare Chooser Extension の一部) を呼び出します。AppleShare エクスターナル・ファイルシステムは、File
Manager コールを AFP コールに変換し、.AFPTranslatorドライバを呼び出します。.AFPTranslatorドライバは、AFP
コールをサーバへ送り、その応答を AppleShare エクスターナル・ファイルシステムに返します。サーバへの接続経路は、コネクション・トランスポート・タイプにより、AppleTalk
か TCP/IP のいずれかになります。AppleShare エクスターナル・ファイルシステムは、応答データがあればそれを変換し、File
Manager に返し、File Manager はアプリケーションに返します。9図 1 に、Macintosh アプリケーションと
AFP サーバの通常のコマンドの流れを示します。

図 1: アプリケーションが File Manager 経由でファイルサーバを使う様子
しかしながら、AFP がサポートする操作のうち、File Manager には該当するものがない場合があります。このような場合アプリケーションは、.AFPTranslatorドライバ経由で
AFP サーバに AFP コマンドを渡さなければなりません。
AFP コマンドでファイルサーバにアクセスするアプリケーションには、ファイルサーバとの間に
AFP セッションが必要です。セッションがない場合は、アプリケーションは、.AFPTranslatorドライバを使い、afpLogin
(あるいは afpLoginCont) でセッションを開かなければなりません。ところが、AFP
ボリュームがすでにひとつでも Macintosh ファイルシステムによってマウントされている場合、ファイルサーバとのセッションはすでに開かれています。そのセッション・リファレンス番号を.AFPTranslator
ドライバ (AppleShare Chooser Extension の別の部分) から取得すれば、そのセッションを使ってファイルサーバに
AFP コマンドが送れます。ただし制約があります。図 2 に、Macintosh アプリケーションが、.AFPTranslator
から借用したセッション・リファレンス番号を使って、.AFPTranslatorドライバ経由で直接
AFP ファイルサーバにアクセスする場合のコマンドの流れを示します。

図 2: アプリケーションが、借用したセッション・リファレンス番号を使い、.AFPTranslatorドライバ経由でファイルサーバを使う様子
TECHNOTE の次の節では、.AFPTranslator ドライバから、マウント済みの
AFP ボリュームの AFP セッション・リファレンス番号を取得する方法を説明します。借用した
AFP セッションを使用する場合に注意すべき制約事項も列挙します。
サーバボリューム情報ステータスコール
AppleShare エクスターナル・ファイルシステムは、File Manager コマンドの AFP コマンドへの変換、AFP
ファイルサーバとのセッションの管理を行います。.AFPTranslator
ドライバへサーバボリューム情報ステータスコール (AFPSVolInfo)
を発行すると、ドライバが保存する重要な情報をいくつか取得することができます。AFPSVolInfo
ステータスコールが返す情報は次のとおりです。
- サーバとのセッションを開くのに使用する AFP のバージョン。これにより、このセッションで使用可能な
AFP コールがわかります。
- AFPセッション・リファレンス番号 - セッション・リファレンス番号は、AFP
コールを行う際に、
.AFPTranslatorドライバに渡します。
- AFP ボリューム ID 番号 - ボリューム ID 番号を必要とする AFP コールに渡す番号です。
- ファイルサーバのインターネット・ソケットアドレス - これは、File Manager の
PBHGetVolParms
関数が GetVolParmsInfoBuffer レコードの vMServerAdr フィールドに返すインターネット・ソケットアドレスと同じです。
- セッション確立のために使用するユーザ認証方式 (UAM) - File Manager の
PBHGetLogInInfo
関数が ioObjType に返すワード値、および File Manager の PBGetVolMountInfo
関数が AFPVolMountInfo レコードの uamType フィールドに返すワード値と同じです。
- セッション確立で使用するユーザ名 - これは、File Manager の
PBHGetLogInInfo
関数が ioObjNamePtr の指す文字列領域に返す文字列、および FileManager
の PBGetVolMountInfo 関数が AFPVolMountInfo レコードの
AFPData フィールド内に返す文字列 (AFPVolMountInfo レコードの
AFPData フィールド内のユーザ名の格納位置は userNameOffset
フィールドで決まります) と同じです。
- サーバボリュームのアイコンとマスク - ディスクドライバへの
csCode = 21
の制御コールが返す 256 バイトのアイコンとマスクと同じです。
- Finder の“情報を見る”ダイアログに (“場所:”に続けて) 表示される文字列。ディスクドライバへの
csCode = 21 の制御コールが返す文字列と同じです。
上記の情報群は、GetVolSessInfoRec レコードに返されます。GetVolSessInfoRec
レコードは次のように定義されています。
GetVolSessInfoRec = RECORD
sessAFPVersion: Integer; {AFP バージョン番号: }
{ 1 = バージョン 1.1 }
{ 2 = バージョン 2.0 }
{ 3 = バージョン 2.1 }
{ 4 = バージョン 2.2 }
sessReferenceNumber: Integer; {AFP セッション・リファレンス番号}
sessAFPVolID: Integer; {AFP ボリューム ID}
sessServerAddress: OTAddressPtr; {サーバインターネットアドレス}
sessUAMType: Integer; {ユーザ認証方式: }
{ 1 = ユーザ認証なし }
{ 2 = クリアテキストパスワード }
{ 3 = 乱数交換 }
{ 6 = 双方向乱数交換 }
sessUserNamePtr: StringPtr; {ユーザ名文字列へのポインタ}
sessVolIconPtr: Ptr; {サーバボリュームのアイコン/マスクへのポインタ}
sessWhereStringPtr: StringPtr; {位置情報 ([場所:]) 文字列へのポインタ}
END;
警告:
sessUserNamePtr、sessVolIconPtr、sessServerAddress、sessWhereStringPtr
は、.AFPTranslator ドライバが保持するデータを指します。使用する前にプログラム側の変数にデータをコピーしなければなりません。 |
.AFPTranslator ドライバの AFPSVolInfo ステータスコールが使用する
ParamBlockRec レコードのフィールドは次のように定義されています。
-> 12 ioCompletion (long) 完了ルーチンへのポインタ
<- 16 ioResult (word) 結果コード
-> 24 ioRefNum (word) AFPTranslator リファレンス番号
-> 26 csCode (word) つねに AFPSVolInfo
-> 28 ioMisc (long) ボリュームの VCB へのポインタ
-> 32 ioBuffer (long) GetVolSessInfoRec へのポインタ
-> 36 ioReqCount (long) 要求するデータのサイズ
<- 40 ioActCount (long) 返されたデータのサイズ
ここからパラメータブロックフィールドに関して詳しく説明します。
ioCompletion (Longword の入力ポインタ) AFPSVolInfo
ステータスコールが非同期で呼ばれた場合は、完了ルーチンへのポインタか NIL
でなければなりません。
ioResult (Word の結果コード) 関数の戻り値
ioRefNum (Word の入力値) .AFPTranslator ドライバのドライバリファレンス番号
csCode (Word の入力値) 常に AFPSVolInfo (124)
ioMisc (Longword の入力ポインタ) ボリュームの制御ブロック
(VCB) へのポインタ
- ioBuffer (Longword の入力ポインタ) サーバボリューム情報が返される GetVolSessInfoRec
へのポインタ
ioReqCount (Longword の入力値) ioBuffer
が指す GetVolSessInfoRec のサイズ
ioActCount (Longword の結果値) ioBuffer
が指す GetVolSessInfoRec に返されたデータのサイズ
AFPSVolInfo ステータスコールは次の結果コードを返します。
noErr (0) エラーなし。
badUnitErr (-21) ドライバリファレンス番号が正しくない。
unitEmptyErr (-22) ドライバリファレンス番号が正しくない。
notOpenErr (-28) ドライバがまだ開かれていない。
statusErr (-18) ドライバはこのステータスコールに応答できない。
paramErr (-50) ioReqCount が GetVolSessInfoRec
レコードが小さすぎることを示しているか、ioMisc で指定されたボリュームが.AFPTranslator
ドライバの所有ではない。
次のコードは、AFPSVolInfo ステータスコールを使って、ボリュームリファレンス番号で指定されたボリュームのサーバボリューム情報を取得する方法を示します。
USES
AppleTalk, Files;
CONST
{ AFP バージョン番号 }
AFPVer1_1 = 1; { AFP バージョン 1.1 }
AFPVer2_0 = 2; { AFP バージョン 2.0 }
AFPVer2_1 = 3; { AFP バージョン 2.1 }
AFPVer2_2 = 4; { AFP バージョン 2.2 }
AFPSVolInfo = 124; { サーバボリューム情報コール }
TYPE
GetVolSessInfoRec = RECORD
sessAFPVersion: Integer; {AFP バージョン番号}
sessReferenceNumber: Integer; {AFP セッション・リファレンス番号}
sessAFPVolID: Integer; {AFP ボリューム ID}
sessServerAddress: OTAddressPtr; {サーバインターネットアドレス}
sessUAMType: Integer; {ユーザ認証方式}
sessUserNamePtr: StringPtr; {ユーザ名文字列へのポインタ}
sessVolIconPtr: Ptr; {サーバボリュームのアイコン/マスクへのポインタ}
sessWhereStringPtr: StringPtr; {位置情報 ([場所:]) 文字列へのポインタ}
END;
FUNCTION GetVolSessionInfo (theVRefNum: Integer;
VAR theVolSessInfoRec: GetVolSessInfoRec): OSErr;
CONST
TSigWord = $4244; { HFS ボリュームシグネチャ }
VAR
pb: ParamBlockRec;
vcbPtr: QElemPtr;
afpTranslatorRefNum: Integer;
err: OSErr;
BEGIN
{ .AFPTranslator ドライバの refNum を取得 }
err := OpenDriver('.AFPTranslator', afpTranslatorRefNum);
IF err noErr THEN
BEGIN { ドライバがオープンできない }
GetVolSessionInfo := err;
Exit(GetVolSessionInfo);
END;
{ ボリュームリファレンス番号で VCB を発見 }
QHdrPtr(vcbPtr) := GetVCBQHdr; { VCB キューヘッダへのポインタ }
vcbPtr := QHdrPtr(vcbPtr)^.qHead; { 最初の VCB へのポインタ }
WHILE (vcbPtr NIL) DO
BEGIN
IF VCB(vcbPtr^).vcbSigWord = TSigWord THEN { HFS ボリューム でなければならない }
IF VCB(vcbPtr^).vcbVRefNum = theVRefNum THEN
Leave; { VCB が見つかった }
vcbPtr := vcbPtr^.vcbQElem.qLink; { 次の VCB }
END;
IF (vcbPtr = NIL) THEN
BEGIN { ボリュームが見つからない }
GetVolSessionInfo := nsvErr;
Exit(GetVolSessionInfo);
END;
{ ボリュームセッション情報を取得するステータスコール }
WITH pb DO
BEGIN
ioRefNum := afpTranslatorRefNum;
csCode := AFPSVolInfo;
ioMisc := Ptr(vcbPtr);
ioBuffer := @theVolSessInfoRec;
ioReqCount := LongInt(sizeof(GetVolSessInfoRec));
END;
GetVolSessionInfo := PBStatus(@pb, FALSE);
END;
FUNCTION DoGetVolSessionInfo (vRefNum: Integer): OSErr;
VAR
err: OSErr;
myVolSessInfoRec: GetVolSessInfoRec;
myIconHandle: Handle;
myUserName: Str31;
myWhereString: Str255;
BEGIN
err := GetVolSessionInfo(vRefNum, myVolSessInfoRec);
IF err = noErr THEN
BEGIN
WITH myVolSessInfoRec DO
BEGIN
{ 文字列変数にユーザ名をコピー }
myUserName := sessUserNamePtr^;
{ ハンドルを割り当て、そこにアイコンを移す }
myIconHandle := NewHandle(kLargeIconSize);
IF myIconHandle = NIL THEN
BEGIN
DoGetVolSessionInfo := MemError;
Exit(DoGetVolSessionInfo);
END;
BlockMove(sessVolIconPtr, myIconHandle^, kLargeIconSize);
{ 位置情報 ([場所:]) 文字列を文字列変数にコピー }
myWhereString := sessWhereStringPtr^;
{ この時点で、myGetVolSessInfoRec からコピーしたか、}
{ まだ myGetVolSessInfoRec に残っている情報はすべて利用可能 }
DisposHandle(myIconHandle);
END;
END;
DoGetVolSessionInfo := err;
END;
セッション借用のルールと制約についての注意: Macintosh ファイルシステムから AFP
セッションを借用するプログラムは、この TECHNOTE に記載されている制約を守らなければなりません。
アップルがこれまで AFPSVolInfo をドキュメントしていなかったのには正当な理由があります。AFP
ファイルサーバはセッションでユーザを区別しており、AppleShare エクスターナル・ファイルシステムは、オープン中の
AFP ボリューム (およびその内容) について一定の仮定に基づいて処理を進めます。Macintosh
ファイルシステムが所有するセッションを不正に使用すると、AppleShare エクスターナル・ファイルシステムやファイルサーバを混乱させてしまう可能性があります。ファイルシステムが所有している
AFP セッションを借用する場合に基本的に守るべきことは次のとおりです。
File Manager 関数でできることは、File Manager 関数を使って行ってください。AFP
コールは絶対使わないでください。
これに該当するのは、ボリューム、ディレクトリ、ファイル、ボリュームのデスクトップ・データベースのオープン/クローズコール、ファイルやデスクトップ・データベースを開いてからでないと使用できないコールなどです。AFP
セッションを閉じるのはもってのほかです。これらの AFP 操作を行う場合は、まず、.AFPTranslatorドライバを使ってファイルサーバとの間に専用の
AFP セッションを開いてください。
ファイルシステムから借用したセッションを使っても安全な AFP コールの一覧を以下に示します。個々の
AFP コールごとに、File Manager 関数ではできないことで、AFP コールでできることを説明します。
一覧はまだ続きますが、以下のコールは、File Manager 関数ではアクセスできない情報
(ProDOS 情報など) を取得したり、設定しなければならない場合のみ使用してください。
afpEnumerate - ProDOS 情報や特定のファイルやディレクトリの属性情報が必要な場合に、ディレクトリの内容を参照するために使用できます。この他の目的には、File
Manager の PBGetCatInfo 関数を使用すべきです。
afpGetVolParms - 特定のサーバボリュームのパラメータを取得するために使用できます。通常の場合には、File
Manager の PBHGetVInfo 関数を使用すべきです。
afpSetDirParms - ProDOS 情報や特定のディレクトリの属性情報を設定したい場合に、指定のディレクトリのパラメータを設定するために使用できます。他のすべての用途には、File
Manager の PBSetCatInfo 関数を使用すべきです。
afpSetFileParms - ProDOS 情報や特定のファイルの属性情報を設定したい場合に、指定のファイルのパラメータを設定するために使用できます。他のすべての用途には、File
Manager の PBSetCatInfo 関数を使用すべきです。
afpGetFlDrParms - ProDOS 情報や特定のファイルやディレクトリの属性情報が必要な場合に、指定のディレクトリやファイルのパラメータを取得するために使用できます。これ以外の用途には、File
Manager の PBGetCatInfo 関数を使用すべきです。
afpSetFlDrParms - ProDOS 情報や特定のファイルやディレクトリの属性情報を設定したい場合に、指定のディレクトリやファイルのパラメータを設定するために使用できます。これ以外の用途には、File
Manager の PBGetCatInfo 関数を使用すべきです。
AppleShare 3.0 (またはそれ以降) の Chooser Extension を System 6 で使用する場合、AFP
2.1 ファイルサーバに対して、次の AFP 2.1 コールを行うことができます。これらのコールは
System 6 の File Manager ではサポートされません。
afpGetSrvrMsg - 上記の一覧を参照してください。
afpCreateID - 指定のファイルに対してユニークな fileID を作成するために使用できます。
afpDeleteID - 指定の fileID のインスタンスをすべて無効にするために使用できます。
afpResolveID - 指定の fileID の情報 (ファイルの位置など)
を取得するために使用できます。
afpExchangeFiles - サーバボリューム上の 2 つのファイルの内容を交換するために使用できます。
- afpCatSearch - 指定の条件と一致するファイルやフォルダを求めてボリュームを検索するために使用できます。
まとめ
Macintosh ファイルシステムではサポートされていない方法で AFP ファイルサーバにアクセスする必要のあるデベロッパは、.AFPTranslator
ドライバへの AFPSVolInfo ステータスコールを使って有益な情報を取得してください。しかしながら、この
TECHNOTE に記載された制約を守り、クライアントの Macintosh や AFP ファイルサーバに問題を起こさないようにしなければなりません。
参考文献
- 『Inside Macintosh』Volume V「The AppleTalk Manager」
- 『M.NW.afpMiscUserCommand』
- 『Inside AppleTalk』第 2 版「AppleTalk Filing Protocol」
- 『AppleShare 3.0 Developer's Kit, AppleTalk』の「Filing Protocol Version 2.1」
|
更新日: 1997 年 9 月 30 日
|