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

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;

警告:
sessUserNamePtrsessVolIconPtrsessServerAddresssessWhereStringPtr は、.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 コールでできることを説明します。

  • afpGetSParms - サーバの時刻やサーバボリュームの一覧を取得するために使用できます。ボリュームごとに、パスワードで保護されているか、Apple II 設定情報を含むかどうかを調べることもできます。
  • afpSetVolParms - ボリュームのバックアップ日付を設定することができます。
  • afpChangePassword - ユーザのパスワードを変更することができます。
  • afpGetUserInfo - 指定されたユーザのユーザ ID やプライマリグループ ID を取得することができます。
  • afpGetSrvrMsg - 現在、最初に表示されるメッセージやサーバのメッセージを取得することができます。このコールは AFP 2.1 サーバでのみサポートされます。注意: サーバメッセージはユーザには該当しません。
  • afpMiscUserCommand - デベロッパ用に予約されています。『Technote 323 Arbitrating Use of afpMiscUserCommand and afpMiscUserWrite』を参照してください。
  • afpMiscUserWrite - デベロッパ用に予約されています。『Technote 323 Arbitrating Use of afpMiscUserCommand and afpMiscUserWrite』を参照してください。

一覧はまだ続きますが、以下のコールは、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 日