/*static char *SCCSID = "@(#)setopnea.c	6.3 92/02/19";*/
#define BSWAP0 BSWAP0

#define INCL_DOSERRORS
#include <os2def.h>
#include <bse.h>
#include <fsh.h>
#include "const.h"
#include "misc.h"
#include "storage.h"
#include "buf.h"
#include "ea.h"
#include "fnode.h"
#include "chain.h"
#include "dir.h"
#include "volume.h"
#include "tables.h"
#include "frame.h"
#include "lw.h"
#include "fsdata.h"
#include "pbmacros.h"
#include "log.h"
#include "pr_debug.h"
#include "pr_ea.h"
#include "pr_fssub.h"
#include "pr_misc.h"

/*
 ***	SetOpenEA - Set EAs during an Open() call.
 *
 *	Set Extended Attributes for a file during an open-replace or create
 *
 *	Entry	poft	= oft of file to set EA's for (Locked or held)
 *		peaop	= pointer to EAOP struct for the EA lists
 *
 *
 *	Exit	0 clear if OK
 *		  *pcbLen = length of new ea list
 *		  *pfDirFlag has DF_NEEDEA bit set
 *				iff the resulting list has EAs marked Need.
 *
 *		error code if not OK
 *		  peaop->oError = offset in FEA buffer of error
 *
 *		POFT IS LOCKED
 *
 *	HISTORY
 *	    19-Sep-89 by JR (John Rogers, JohnRo@Microsoft)
 *		- Avoid warnings from Microsoft C 5.2 (on slash-slash comments).
 */

UINT far
SetOpenEA(POFT poft,PEAOP peaop,PULONG pcbLen,PBYTE pfDirFlag,BOOL fVMLock,PFRAME pfrm)
{
    LHANDLE lhFEA, lhGEA;  /*  Lock handles for EAs  */
    PFEALIST pfeal;
    PGEALIST pgeal;
    USHORT  usRet = 0;
    UINT    erc;
    USHORT  cbLen;	/* length of new EA list.  Also used as
			 * error return code from PROBEBUF.
			 */

    /*
     * Convert our hold to a lock if we have to.
     */
    if( (poft->bFlag & OTF_LCK) == 0 ) {

	/* We've got to convert our hold to a lock. */
	DecrHoldsOFT (poft);

	/* wait until it's lockable */
	LockOFT( poft,pfrm );

	/* Lock it for us! */
	SetLockOFT(poft);
    }


    /*
     *	The user wants to set EAs.  First, we
     *	lock the EA pointers' segments into place
     *	so we can use them with impunity at lower
     *	levels.
     */

    CHECKSWAP(&swapBSWAP0);
    if( (erc = LockEAs(peaop,LEAS_SET,&lhFEA,&lhGEA,&pfeal,&pgeal,fVMLock,pfrm)) ==
							       NO_ERROR ) {

	/* don't waste time initializing cbLen here because fReplace == TRUE */
	CHECKSWAP(&swapBSWAP0);
	erc = SetEA( pfeal, poft, &usRet, &cbLen, TRUE, pfrm);

   if (fVMLock) {
	  CHECKSWAP(&swapBSWAP0);
	  UnlockEAs(lhFEA,lhGEA,pfrm);
    }
   }

    if (erc == NO_ERROR) {
	/* set the new EA len and the number of need FEAs for return */
	*pcbLen = (ULONG)cbLen;

	/* update the need eas bit in the dirent */
	*pfDirFlag = (*pfDirFlag & ~DF_NEEDEAS) | (BYTE)usRet;


    } else {

      if (fVMLock) {

	   /*  We also have to set the usRet field in the
	    *  user's EAOP, which has to be probed first.
	    *
	    *  note that cbLen gets reused as an error return code.
	    */
	   MAYBLOCK(
	      cbLen = FSH_PROBEBUF( PB_OPWRITE, (char far *)peaop, sizeof(EAOP) )
	   )

	    if (cbLen == NO_ERROR)
	        peaop->oError = usRet;

      } else /* fVMLock == FALSE */
	          peaop->oError = usRet;
    }
    return erc;
}
