/*static char *SCCSID = "@(#)fs_ocrea.c	6.4 92/02/21";*/
#define _BTXT _BTXT

#define INCL_DOSERRORS
#define INCL_DOSINFOSEG
#include <os2def.h>
#include <bse.h>

#include <fsh.h>
#include "api.h"
#include "const.h"
#include "misc.h"
#include "chain.h"
#include "buf.h"
#include "dir.h"
#include "storage.h"
#include "volume.h"
#include "tables.h"
#include "pb_ifs.h"
#include "pbmacros.h"
#include "superb.h"
#include "lw.h"
#include "frame.h"
#include "fsdata.h"
#include "filemode.h"
#include "tefti.h"
#include "fnode.h"
#include "heap.h"
#include "shutdown.h"
#include "pr_fsd.h"
#include "pr_CACHE.h"
#include "pr_FCN.h"
#include "pr_FSSUB.h"
#include "pr_HEAP.h"
#include "pr_MISC.h"
#include "pr_WRSUB.h"
#include "pr_DEBUG.h"
#include "mmph.h"      /* performance hook macros */

/*
 *	HISTORY
 *	    31-Jul-1990 by JR (John Rogers, JohnRo@Microsoft)
 *		- DCR MS 2026: Open mode changes.
 *	    26-May-1989 by JR (John Rogers, JohnRo@Microsoft)
 *		- DCR 259.2: added counting of write threads for shutdown.
 *		- DCR 259.2: changed names of macros in "frame.h".
 */

#ifdef DEBUG
BOOL fInOpen = FALSE;
#endif

#ifdef MINIFSD
extern struct sffsd far *sffsdlist;
#endif


int far pascal
FS_OPENCREATE (pcdfsi, pcdfsd, pcName, usCurDirEnd, psffsi, psffsd, ulOpenMode,
	      usOpenFlag, pusRetAction, usAttr, pcEABuf, pfGenFlag)
struct cdfsi far *	pcdfsi;		/* File system indep. directory */
struct cdfsd far *	pcdfsd;		/* file system dep. directory	*/
PCHAR			pcName;		/* canonicalized file name	*/
USHORT			usCurDirEnd;	/* index of end of cur dir in pcName */
struct sffsi far *	psffsi;		/* file sys indep open file	*/
struct sffsd far *	psffsd;		/* file sys depend open file	*/
ULONG			ulOpenMode;	/* sharing and access mode	*/
USHORT			usOpenFlag;	/* action if present or absent	*/
PUSHORT			pusRetAction;	/* return for action code	*/
USHORT			usAttr;		/* file attributes		*/
PCHAR			pcEABuf;	/* Extended Attribute buffer	*/
PUSHORT			pfGenFlag;	/* return for Need eas bit	*/
{
	PCRACKEDPATH pcp = NULL;/*  points to cracked path for Open	*/
	SHUTDOWN_LOCAL_VARS;
	USHORT us;		/*  stores return code from Open	*/
	FRAME  frm;

	MMPHPreFS_Open();	/* performance hook (330D) */

	INCR_WRITE_THREADS;		/* Tell shutdown we're writing. */

	frm.usHardErr = NO_ERROR;
	frm.fRecheckAddr = TRUE;

#ifdef TEFTI
	ClearCounter (0);
	StartCounter (0);
#endif

#ifdef DEBUG
	fInOpen = TRUE;
#endif

#ifdef DEBUG
	if (pcdfsi) {
	    if (psffsi->sfi_hVPB != pcdfsi->cdi_hVPB) {
		dprintf ("%s (%d): psffsi->sfi_hVPB != pcdfsi->cdi_hVPB\n",
			 __FILE__, __LINE__);
		Int3 ();
	    }
	}
#endif

	if ((us = CrackPath(psffsi->sfi_hVPB,pcName,&pcp,&frm)) == NO_ERROR) {

	    if ((ulOpenMode & OPEN_DIRECT) == 0) {
		us = Open((USHORT) ulOpenMode,
			  usOpenFlag,
			  usAttr,
			  psffsi->sfi_size,
			  pcp,
			  &(psffsi->sfi_size),
			  &((PPB_SFD)(psffsd->sfd_work))->pfht,
			  pusRetAction,
			  pcEABuf,
			  pfGenFlag,
			  &(psffsi->sfi_DOSattr),
			  &frm);



	    }
	    else { /* direct access Open */
		us = OpenDirect((USHORT)ulOpenMode,
				pcp,
				&(psffsi->sfi_size),
				&((PPB_SFD)(psffsd->sfd_work))->pfht,
				&frm);
		*pusRetAction = OPEN_EXISTS;
	    }
	}

	if (pcp != NULL)
	    RetHeap (pcp);

#ifdef DEBUG
	VBS ();
	fInOpen = FALSE;
#endif
#ifdef TEFTI
	StopCounter (0);
#endif

	/*
	 * Nothing from here on will modify the disk, and we've got to start
	 * looking at error codes (which have "return" statements), so this is
	 * a good place to tell shutdown that we're done writing.
	 */
	DECR_WRITE_THREADS;

	if (us != NO_ERROR)
	{
		MMPHPostFS_Open();	  /* performance hook (330D) */
		return (us);
	}

#ifdef TEFTI
	LatchCounter (0);
	dprintf (__FILE__ ": %dus\n", Get_cntCounter (0));
#endif

#ifdef MINIFSD
/*
 *	In the mini-FSD, we have to save pointers to the sf_fsi field
 *	for each file that is left open at the end of stage two.  To do
 *	this, we store psffsi in the second dword of psffsd, and link
 *	the psffsd's together with the third dword.
 */
	((PPB_SFD)(psffsd->sfd_work))->psffsi = psffsi;
	((PPB_SFD)(psffsd->sfd_work))->fwd = sffsdlist;
	sffsdlist = psffsd;
#endif

	MMPHPostFS_Open();	  /* performance hook (330D) */
	return (NO_ERROR);

	/* to satisfy /W3 */
	pcdfsi; pcdfsd; usCurDirEnd;
#ifdef MINIFSD
	pcEABuf;
#endif
}
