ADC Membership Technical Business Join ADC
Search Advanced Search
Technical Note TN1106
Update: Borrowed AFP Sessions

CONTENTS

This Technote shows how to borrow the session reference number of an AFP volume mounted by the Macintosh File System. It also shows how to retrieve other information from the file system for a mounted AFP volume. This revision of the Borrowed AFP Sessions Technote applies to systems that are using AppleShare Client 3.7 and later. Previous versions of the AppleShare client should use the information contained in
Technote NW 16.


* The updated information is in bold and italic.



 Updated: [Feb 09 1998]






Introduction

The AppleShare Chooser extension allows Macintosh applications to perform almost all volume and file access operations on an AppleTalk Filing Protocol (AFP) file server by translating File Manager commands to their AFP equivalent commands. To access a file server, an application normally calls the File Manager. The File Manager calls the AppleShare external file system (part of the AppleShare Chooser extension) which translates the File Manager command into an AFP call. The AppleShare external file system then calls the .AFPTranslator driver. The .AFPTranslator driver delivers the AFP call to the server and returns the reply to the AppleShare external file system. The connection to the server can be either over AppleTalk or TCP/IP depending on the connection transport type. The AppleShare external file system translates the reply data (if any) and returns it to the File Manager which returns it to the application. Figure 1 shows the normal flow of commands between a Macintosh application and an AFP file server.

AFP File Server

Figure 1. Application Using the File Server Through the File Manager

However, there are a few instances for which no equivalent File Manager commands exist to perform operations supported by AFP. In those instances, an application must use the .AFPTranslator driver to access the file server with AFP commands.

Applications accessing a file server with AFP commands need to have an open AFP session with the file server. When no session exists, the application must use the .AFPTranslator driver to open an AFP session with the afpLogin (and possibly afpLoginCont) command. However, when an AFP volume on the file server is already mounted by the Macintosh File System, a session is already open with the file server. If the session reference number is retrieved from the .AFPTranslator driver (another part of the AppleShare Chooser extension), that session can be used, with restrictions, to access the file server with AFP commands. Figure 2 shows the flow of commands when a Macintosh application accesses an AFP file server directly through the .AFPTranslator driver using the session reference number borrowed from the .AFPTranslator driver.

AFP Translator

Figure 2. Application Using File Server Through the .AFPTranslator Driver with Borrowed Session Reference Number

The next section of this Technote tells how to get the AFP session reference number for a mounted AFP volume from the .AFPTranslator driver. It also lists the restrictions you must observe when using the borrowed AFP session.


Back to top

The Server Volume Information Status Call

The AppleShare external file system performs the translation of File Manager commands to AFP commands and maintains sessions with AFP file servers. The server volume information (AFPSVolInfo) status call to the .AFPTranslator driver can be used to retrieve several important pieces of information stored by the driver. The information returned by the AFPSVolInfo status call is:

  • the AFP version used to open the session with the server. This lets you know what possible AFP calls can be made with this session.

  • the AFP session reference number. The session reference number is passed to the .AFPTranslator driver whenever you make an AFP call.

  • the AFP volume ID number. This is the number you pass to AFP calls that require the volume ID number.

  • the file server's internet socket address. This is the same internet socket address returned by the File Manager PBHGetVolParms function in the vMServerAdr field of the GetVolParmsInfoBuffer record. It is a pointer to an OTAddress structure.

  • the user authentication method (UAM) used to establish the session. This is the same word value returned by the File Manager PBHGetLogInInfo function in ioObjType and by the File Manager PBGetVolMountInfo function in the uamType field of the AFPVolMountInfo record.

  • the user name used to establish the session. This is the same string returned by the File Manager PBHGetLogInInfo function in the string pointed to by ioObjNamePtr and by the File Manager PBGetVolMountInfo function as part of the AFPData field in the AFPVolMountInfo record (the exact location of the user name in the AFPData field in the AFPVolMountInfo record is determined by the userNameOffset field).

  • the server's volume icon and mask. This is the same 256-byte icon and mask returned by a control call to the disk driver with csCode = 21.

  • the string displayed by the Finder's Get Info dialog (after the word "Where:"). This is the same string returned by a control call to the disk driver with csCode = 21.

The information list above is returned in a GetVolSessInfoRec record. The GetVolSessInfoRec record is defined as follows:



GetVolSessInfoRec = RECORD
        sessAFPVersion: Integer;           {AFP version number: }
                                           {    1 = version 1.1 }
                                           {    2 = version 2.0 }
                                           {    3 = version 2.1 }
                                           {    4 = version 2.2 }
        sessReferenceNumber: Integer;      {AFP session reference number}
        sessAFPVolID: Integer;             {AFP volume identifier}
        sessServerAddress: OTAddressPtr;   {server internet address}
        sessUAMType: Integer;              {user authentication method: }
                                           {    1 = 'No User Authent' }
                                           {    2 = 'Cleartxt Passwrd' }
                                           {    3 = 'Randnum Exchange' }
                                           {    6 = '2-Way Randnum exchange' }
        sessUserNamePtr: StringPtr;        {ptr to user name string}
        sessVolIconPtr: Ptr;               {ptr to server volume icon/mask}
        sessWhereStringPtr: StringPtr;     {ptr to "where" information string}
      END;


WARNING:
sessUserNamePtr, sessVolIconPtr, sessServerAddress , and sessWhereStringPtr point to data owned by the .AFPTranslator driver. You must copy that data into your program variables before using it.



The fields in the ParamBlockRec record used for the AFPSVolInfo status call to the .AFPTranslator driver are defined as follows:

-> 12 ioCompletion long pointer to completion routine

<- 16 ioResult word result code

-> 24 ioRefNum word .AFPTranslator reference number

-> 26 csCode word always AFPSVolInfo

-> 28 ioMisc long pointer to volume's VCB

-> 32 ioBuffer long pointer to GetVolSessInfoRec

-> 36 ioReqCount long size of data requested

<- 40 ioActCount long size of data returned

 

Here are the detailed descriptions of the parameter block fields:

  • ioCompletion Longword input pointer: If the AFPSVolInfo status cell is called asynchronously, this must be a pointer to the completion routine or NIL.

  • ioResult Word result value: The result code from the function.

  • ioRefNum Word input value: The driver reference number of the .AFPTranslator driver.

  • csCode Word input value: Always AFPSVolInfo (124).

  • ioMisc Longword input pointer: A pointer to the volume's volume control block (VCB).

  • ioBuffer Longword input pointer: A pointer to the GetVolSessInfoRec where the server volume information is returned.

  • ioReqCount Longword input value: The size of the GetVolSessInfoRec pointed to by ioBuffer.

  • ioActCount Longword result value: The size of the data returned in the GetVolSessInfoRec pointed to by ioBuffer.

The following result codes can be returned by the AFPSVolInfo status call:

  • noErr 0 No error.

  • badUnitErr -21 The driver reference number is bad.

  • unitEmptyErr -22 The driver reference number is bad.

  • notOpenErr -28 The driver isn't open.

  • statusErr -18 The driver can't respond to this status call.

  • paramErr -50 Either ioReqCount indicates the GetVolSessInfoRec record is too small, or the volume specified by ioMisc is not owned by the .AFPTranslator driver.

The following code shows how to use the AFPSVolInfo status call to get the server volume information for the volume specified by its volume reference number.



USES
      AppleTalk, Files;

    CONST
      { AFP version numbers }
      AFPVer1_1 = 1;  { AFP version 1.1 }
      AFPVer2_0 = 2;  { AFP version 2.0 }
      AFPVer2_1 = 3;  { AFP version 2.1 }
      AFPVer2_2 = 4;  { AFP version 2.2 }

      AFPSVolInfo = 124;  { server volume information call }

    TYPE
      GetVolSessInfoRec = RECORD
          sessAFPVersion: Integer;           {AFP version number}
          sessReferenceNumber: Integer;      {AFP session reference number}
          sessAFPVolID: Integer;             {AFP volume identifier}
          sessServerAddress: OTAddressPtr;  {server internet address}
          sessUAMType: Integer;              {user authentication method}
          sessUserNamePtr: StringPtr;        {ptr to user name string}
          sessVolIconPtr: Ptr;               {ptr to server volume icon/mask}
          sessWhereStringPtr: StringPtr;     {ptr to "where" information string}
        END;

    FUNCTION GetVolSessionInfo (theVRefNum: Integer;
                 VAR theVolSessInfoRec: GetVolSessInfoRec): OSErr;
      CONST
        TSigWord = $4244; { HFS volume signature }
      VAR
        pb: ParamBlockRec;
        vcbPtr: QElemPtr;
        afpTranslatorRefNum: Integer;
        err: OSErr;
    BEGIN
      { get the .AFPTranslator driver refNum }
      err := OpenDriver('.AFPTranslator', afpTranslatorRefNum);
      IF err <> noErr THEN
        BEGIN { couldn't open the driver }
          GetVolSessionInfo := err;
          Exit(GetVolSessionInfo);
        END;

      { find the VCB with the volume reference number }
      QHdrPtr(vcbPtr) := GetVCBQHdr;  { pointer to VCB queue header }
      vcbPtr := QHdrPtr(vcbPtr)^.qHead;  { pointer to first VCB }
      WHILE (vcbPtr <> NIL) DO
        BEGIN
          IF VCB(vcbPtr^).vcbSigWord = TSigWord THEN { must be HFS volume }
            IF VCB(vcbPtr^).vcbVRefNum = theVRefNum THEN
              Leave;  { we found the VCB }
          vcbPtr := vcbPtr^.vcbQElem.qLink;  { next VCB }
        END;
      IF (vcbPtr = NIL) THEN
        BEGIN  { couldn't find the volume }
          GetVolSessionInfo := nsvErr;
          Exit(GetVolSessionInfo);
        END;

      { make the status call to get the volume session info }
      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
              { copy user name into a string variable }
              myUserName := sessUserNamePtr^;

              { allocate a handle and move the icon into it }
              myIconHandle := NewHandle(kLargeIconSize);
              IF myIconHandle = NIL THEN
                BEGIN
                  DoGetVolSessionInfo := MemError;
                  Exit(DoGetVolSessionInfo);
                END;
              BlockMove(sessVolIconPtr, myIconHandle^, kLargeIconSize);

              { copy where information string into a string variable }
              myWhereString := sessWhereStringPtr^;

              { at this point, you can use all of the information just copied }
              { from myGetVolSessInfoRec or still in myGetVolSessInfoRec }

              DisposHandle(myIconHandle);
            END;
        END;
      DoGetVolSessionInfo := err;
    END;


Session Borrowing Rules and Restrictions Warning: The restrictions listed in this Note must be observed when your program borrows an AFP session owned by the Macintosh File System.

There is a good reason why Apple has not documented the AFPSVolInfo status call in the past. AFP file servers differentiate users by their sessions and the AppleShare external file system makes certain assumptions about AFP volumes (and their contents) that it has open. If the session owned by the Macintosh File System is used improperly, you can confuse the AppleShare external file system or the file server. The basic rule you should use when borrowing an AFP session owned by the file system is

If it can be done with File Manager functions, use the File Manager functions--don't use AFP calls.

That means you shouldn't open or close volumes, directories, files, or a volume's desktop database, you shouldn't use calls that require a file or desktop database to be open, and you definitely should not close the AFP session. If you need to do any of those AFP operations, you should use the .AFPTranslator driver to open your own AFP session with the file server.

The following is a list of AFP calls that are safe to use with a session borrowed from the file system. For each AFP call, there's an description of what you can do with the call that you cannot do with the File Manager functions.

  • afpGetSParms This call can be used to retrieve the server time and the list of server volumes. For each volume, you also can determine if the volume is password-protected and if the volume contains Apple II configuration information.

  • afpSetVolParms This call can be used to set the backup date of a volume.

  • afpChangePassword This call can be used to change the user's password.

  • afpGetUserInfo This call can be used to retrieve the specified user's user ID or primary group ID.

  • afpGetSrvrMsg This call can be used to retrieve the current greeting message or server message. This call is only supported by AFP 2.1 servers. Note: the server message may not be applicable to the user.

  • afpMiscUserCommand reserved for developer use. See Technote #323, "Arbitrating Use of afpMiscUserCommand and afpMiscUserWrite."

  • afpMiscUserWrite reserved for developer use. See Technote #323, "Arbitrating Use of afpMiscUserCommand and afpMiscUserWrite."

The list continues. However, these calls should be used only when you need to retrieve or set information (such as ProDOS information) that is inaccessible through File Manager functions.

  • afpEnumerate This call can be used to list the contents of a directory when either ProDOS information or specific file or directory attribute information is needed. For all other purposes, the File Manager's PBGetCatInfo function should be used.

  • afpGetVolParms This call can be used to retrieve the parameters for a particular server volume. For most purposes, the File Manager's PBHGetVInfo function should be used instead.

  • afpSetDirParms This call can be used to set parameters for a specified directory when either ProDOS information or specific directory attribute information must be set. For all other purposes, the File Manager's PBSetCatInfo function should be used.

  • afpSetFileParms This call can be used to set parameters for a specified file when either ProDOS information or specific file attribute information must be set. For all other purposes, the File Manager's PBSetCatInfo function should be used.

  • afpGetFlDrParms This call can be used to retrieve the parameters for a specified file or directory when either ProDOS information or specific file or directory attribute information is needed. For all other purposes, the File Manager's PBGetCatInfo function should be used.

  • afpSetFlDrParms This call can be used to set parameters for a specified file or directory when either ProDOS information or specific file or directory attribute information must be set. For all other purposes, the File Manager's PBSetCatInfo function should be used.

If the AppleShare 3.0 (or later) Chooser extension is used with System 6, you can make the following AFP 2.1 calls to an AFP 2.1 file server. These calls are not supported by the System 6 File Manager.

  • afpGetSrvrMsg See description in list above.

  • afpCreateID This call can be used to create a unique file ID for a specified file.

  • afpDeleteID This call can be used to invalidate all instances of the specified file ID.

  • afpResolveID This call can be used to return information (including the file location) of the specified file ID.

  • afpExchangeFiles This call can be used to exchange the contents of two files on a server volume.

  • afpCatSearch This call can be used to search a volume for files or folders that match specified criteria.

Back to top

Conclusion

The AFPSVolInfo status call to the .AFPTranslator driver returns useful information for developers who need to access an AFP file server in ways not supported by the Macintosh File System. However, the restrictions lists in this note must be observed to prevent problems on the client Macintosh or the AFP file server.


Back to top

References

Inside Macintosh, Volume V, The AppleTalk Manager

M.NW.afpMiscUserCommand

Inside AppleTalk, Second Edition, AppleTalk Filing Protocol

AppleShare 3.0 Developer's Kit, AppleTalk Filing Protocol Version 2.1


Back to top


Downloadables

Acrobat

Acrobat version of this Note (164K).

Download




Back to top


Technical Notes by Date | Number | Technology | Title
Developer Documentation | Technical Q&As | Development Kits | Sample Code




Gray line

Contact ADC |  ADC Site Map |  ADC Advanced Search
For information about Apple Products, please visit Apple.com.
Contact Apple | Privacy Notice
Copyright © 2002 Apple Computer, Inc. All rights reserved.
1-800-MY-APPLE