CBuffFileStream/FilePermUtils.c

/*
    File:       FilePermUtil.c
 
    Contains:   Get file premissions.
 
    Written by: Tim Carroll
 
    Copyright:  Copyright (c) 1999 Apple Computer, Inc., All Rights Reserved.
 
                You may incorporate this Apple sample source code into your program(s) without
                restriction. This Apple sample source code has been provided "AS IS" and the
                responsibility for its operation is yours. You are not permitted to redistribute
                this Apple sample source code as "Apple sample source code" after having made
                changes. If you're going to re-distribute the source, we require that you make
                it clear in the source that the code was descended from Apple sample source
                code, but that you've made changes.
 
*/
 
#include <Types.h>
#include <Files.h>
 
#include "FilePermUtils.h"
 
 
// --------------------------------
//     GetPermission
// --------------------------------
 
//  This function returns the File Manager permissions of an open file
//  specified by refNum. Any errors are returned in the function result.
//  If the result is noErr, then permission will contain fsRdPerm, fsRdWrPerm,
//  or fsRdWrShPerm.
 
OSErr  GetPermission(short refNum, short *permission)
{
    OSErr                  result;
    FCBPBRec               fcbPB;
    HParamBlockRec         pb;
    GetVolParmsInfoBuffer  buffer;
    
    enum
    {
        fcbFlgWMask        = 0x0100,     /* write permissions bit in FCBFlags */
        fcbFlgSMask        = 0x1000,     /* shared-write bit in FCBFlags */
        vcbWrProtMask      = 0x8080,     /* hardware and software locked bits */
                                         /* in vcbAtrb */
        userWriteACAccess  = 0x04000000  /* user has write access to directory */
    };
    
    /* Get the access path info from the FCB */
    fcbPB.ioNamePtr = NULL;
    fcbPB.ioVRefNum = 0;
    fcbPB.ioRefNum = refNum;  /* check this access path */
    fcbPB.ioFCBIndx = 0;
    result = PBGetFCBInfoSync(&fcbPB);
    if ( result == noErr )
    {
        /* Now, look at ioFCBFlags to see what the File Manager thinks */
        /* it can do with this file */
        
        if ( (fcbPB.ioFCBFlags & fcbFlgSMask) != 0 )
        {
            /* shared bit is set in the FCB */
            *permission = fsRdWrShPerm;  /* shared bit is set in the FCB */
        }
        else if ( (fcbPB.ioFCBFlags & fcbFlgWMask) != 0 )
        {
            /* Write bit is set in the FCB, but a locked volume or */
            /* a read-only folder could squelch that idea. */
            
            /* First, see if the volume supports AFP access control. */
            pb.ioParam.ioNamePtr = NULL;
            pb.ioParam.ioVRefNum = fcbPB.ioFCBVRefNum;
            pb.ioParam.ioBuffer = (Ptr)&buffer;
            pb.ioParam.ioReqCount = sizeof(buffer);
            result = PBHGetVolParmsSync(&pb);
            if ( (result == noErr) && 
                 ((buffer.vMAttrib & (1L << bAccessCntl)) != 0) )
            {
                /* Use GetDirAccess to see if we can really write */
                pb.accessParam.ioNamePtr = NULL;
                pb.accessParam.ioVRefNum = fcbPB.ioFCBVRefNum;
                pb.fileParam.ioDirID = fcbPB.ioFCBParID;
                result = PBHGetDirAccessSync(&pb);
                if ( result == noErr )
                {
                    if ( (pb.accessParam.ioACAccess & userWriteACAccess) != 0
)
                    {
                        /* this user has folder write access */
                        *permission = fsRdWrPerm;
                    }
                    else
                    {
                        /* this user hasn't folder write access */
                        *permission = fsRdPerm;
                    }
                }
            }
            else
            {
                /* GetVolParms isn't supported or */
                /* the volume doesn't support AFP access control */
                
                /* Check for locked volume that will prevent writes */
                pb.volumeParam.ioNamePtr = NULL;
                pb.volumeParam.ioVRefNum = fcbPB.ioFCBVRefNum;
                pb.volumeParam.ioVolIndex = 0;    /* use ioVRefNum only */
                result = PBHGetVInfoSync(&pb);
                if ( result == noErr )
                {
                    if ( (pb.volumeParam.ioVAtrb & vcbWrProtMask) != 0 )
                    {
                        /* locked volume, it can't really write */
                        *permission = fsRdPerm;
                    }
                    else
                    {
                        /* real write access */
                        *permission = fsRdWrPerm;
                    }
                }
            }
        }
        else
        {
            /* write bit wasn't set in FCB */
            *permission = fsRdPerm;
        }
    }
    
    return ( result );
}