/*static char *SCCSID = "@(#)dirtymsg.c	6.2 92/01/31";*/
#define _BTXT _BTXT
/* BUGBUG: Make sure the INTERR (unexpected CRITERROR) is never called. */
/* BUGBUG: Remove "extraneous" #if defined(TRACE_STACK_DEPTH)? */

#include <os2def.h>		/* PSZ and so on. */
#include <bse.h>		/* Needed by <fsd.h>. */
#include <fsd.h>		/* struct vpfsi, etc. */
#include <fsh.h>		/* FSH_CRITERROR(), FSH_GETVOLPARMS(), CE_xxx */

#include "const.h"
#include "misc.h"
#include "chain.h"
#include "buf.h"
#include "dir.h"
#include "heap.h"		/* Needed by "pr_heap.h". */
#include "lw.h"			/* Needed by "fsdata.h". */
#include "message.h"		/* MESSAGE, PMESSAGE. */
#include "storage.h"
#include "volume.h"		/* PVOLTAB. */
#include "frame.h"		/* Needed by "pbmacros.h". */
#include "fsdata.h"		/* Needed by "pbmacros.h". */
#include "pbmacros.h"		/* MAYBLOCK(). */
#include "tables.h"
#include "pbmsg.h"
#if defined(DEBUG) || defined(TRACE_STACK_DEPTH)
    #include "pr_DEBUG.h"
#endif

#include "pr_HEAP.h"		/* GHSFar(), RetHeap(). */
#include "pr_MISC.h"		/* INTERR(). */
#include "pr_FSINI.h"		/* My prototype. */

/* This is the original version of the error message; we copy and modify it. */
/* MSG_HPFS_VOLUME_DIRTY */
extern MESSAGE _TXT_MSG_HPFS_VOLUME_DIRTY;

/*
 ***	DirtyMountMessage() - display message about dirty mount of volume
 *
 *	This function is called during stages 1-3 of the boot sequence, for each
 *	dirty volume which is mounted.  It displays a popup, giving the gory
 *	details, including the drive ID (e.g. "C:").  In theory, the user will
 *	just press ENTER to acknowledge it.
 *
 *	Unfortunately, because generating this message may take place before
 *	the hard error daemon has been started, we have to use a restricted
 *	version of FSH_CRITERROR.  This version, created by Rajen Shah
 *	(RajanS@Microsoft), doesn't allow any substitions within the message.
 *	So, we have to copy the message text onto the heap and do our own
 *	substition.  Ugly, but it shouldn't happen that often.
 *
 *	Entry	pvol	   = far pointer to VOLTAB entry
 *
 *	Exit	Just returns (no errors code or anything).
 *		May block.
 *
 *	HISTORY
 *	    06-Oct-89 by JR (John Rogers, JohnRo@Microsoft)
 *		- PTR B786062: Don't INTERR or GP fault on missing %1 in msg.
 *	    11-Aug-1989 by JR (John Rogers, JohnRo@Microsoft)
 *		- PTR B705990: Created DirtyMountMessage() from scratch.
 */

void far pascal
DirtyMountMessage (PVOLTAB pvol, PFRAME pfrm)
{
    CHAR chDrive;			/* E.g. 'D' for "D:". */

    {
	struct vpfsi far * pvpfsi;
	struct vpfsd far * pvpfsd;

	/* Get pointer to file-system-independent volume info. */
	FSH_GETVOLPARM (pvol->hVPB,	/* hVPB, */
			&pvpfsi,	/* ppvpfsi, */
			&pvpfsd);	/* ppvpfsd. */

	/*
	 * Get drive char, by taking advantage of the fact that the
	 * "device handle" is really a far pointer to the DPB, and the
	 * first byte of the DPB is a drive number (where 0 indicates A:,
	 * etc).
	 */
	chDrive = *((PCHAR) (pvpfsi->vpi_hDEV)) + 'A';
    }

    {
	USHORT cchMessage = _TXT_MSG_HPFS_VOLUME_DIRTY.cchMessage +
				 sizeof ( (char)('\0') );
	PSZ pszChangedMessage;

	/* Allocate memory for our copy of message text. */
	if ( (pszChangedMessage = GHS(cchMessage,pfrm)) == NULL) {
	    INTERR(PBMSG_DIRTYMSG_NOHEAP);
	}

	/* Copy the message. */
	(void) memcpy (pszChangedMessage,
		       _TXT_MSG_HPFS_VOLUME_DIRTY.pszMessage,
		       cchMessage);

	/* Change "%1" to "D:" in our copy of the message. */
	{
	    PSZ pszPercent = pszChangedMessage; /* Updated to -> '%1'. */
	    USHORT usRet =
		FSH_FINDCHAR(
			     (USHORT) 2,	/* nChars, */
			     (PSZ) "%1",	/* pChars (far *), */
			     & pszPercent);	/* ppsz (updated). */
	    if (usRet == 0) {
		*pszPercent = chDrive;		/* Change "%" to "D"... */
		*++pszPercent = ':';		/* and '1' to ':'. */
	    }
	} /* scope of pszPercent, usRet */

	/*
	 * Use the FSH critical error handler to do a popup and give the
	 * user a chance to abort or acknolwedge the situation.  (We don't
	 * have to request abort; it's always allowed.)
	 */
	{
	    USHORT usAction;

	    MAYBLOCK(
		usAction = FSH_CRITERROR(
			    cchMessage,			/* cbMessage */
			    pszChangedMessage,		/* pMessage */
			    (USHORT) 0,			/* nsubs */
			    (PSZ) 0,			/* pSubs (char far *) */
			    CE_ALLACK | CE_ALLFAIL));	/* fAllowed */
#ifdef INTERR_ON_FAIL
	    if (usAction != CE_RETACK) {
		INTERR(PBMSG_DIRTYMSG_CRITERR);
	    }
#endif
	} /* scope of usAction */

	/* Free memory for our copy. */
	RetHeap(pszChangedMessage);

    } /* scope of cchMessage, pszChangedMessage */
}
