Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

277 lines
6.6 KiB

/*****************************************************************************
*
* BACK.C
*
* Copyright (C) Microsoft Corporation 1990.
* All Rights reserved.
*
******************************************************************************
*
* Module Intent
* Back list stuff.
*
*****************************************************************************/
#include "help.h"
#pragma hdrstop
/*
* fBackMagic is true if we're in the processing of jumping because
* we're backing up. This tells us not to push the old state onto
* the backtrack stack (instead it's being popped.)
* tlpBackMagic is also saved and compared just for safety.
*/
BOOL fBackMagic;
extern TLP tlpBackMagic;
/*****************************************************************************
* *
* Defines *
* *
*****************************************************************************/
#define STACKSIZE 21 // default stack size (1 extra for implementation)
/*****************************************************************************
* *
* Typedefs *
* *
*****************************************************************************/
// Back stack element. The TLP and ifm are for DIFFERENT topics.
typedef struct {
union {
TLP tlp; // TLP of Previous Topic (WinHelp)
CTX ctx; // CTX of Previous Topic (UDH, etc.)
};
INT16 ifm; // index to cached FM of Current help file
BOOL16 fCtx; // TRUE -> ctx above, else fcl
} BSE;
/***************************************************************************
FUNCTION: RcBackInit
PURPOSE: Initialize the back history stack
PARAMETERS:
phstackBack
RETURNS:
COMMENTS:
MODIFICATION DATES:
23-Jul-1994 [ralphw]
***************************************************************************/
RC STDCALL RcBackInit(int iWindow)
{
if (ahwnd[iWindow].hstackBack)
return rcSuccess;
return RcInitStack(&ahwnd[iWindow].hstackBack, STACKSIZE,
sizeof(BSE), NULL);
}
void STDCALL RcBackFini(int iWindow)
{
if (iWindow == MAIN_HWND)
return; // never destroy main window back tree
if (ahwnd[iWindow].hstackBack) {
RcFiniStack(ahwnd[iWindow].hstackBack);
ahwnd[iWindow].hstackBack = NULL;
}
}
BOOL STDCALL FBackAvailable(int iWindow)
{
#ifdef _DEBUG
int cBack = (ahwnd[iWindow].hstackBack) ?
CElementsStack(ahwnd[iWindow].hstackBack) : 0;
#endif
return (ahwnd[iWindow].hstackBack &&
CElementsStack(ahwnd[iWindow].hstackBack) > 1);
}
/***************************************************************************\
*
- Function: RcBackPush( tlp, fm )
-
* Purpose: Push info onto the Back stack.
*
* ASSUMES
*
* args IN: tlp - of the topic we just left
* fm - of the topic we just entered
*
* globals IN: hstackBack - If empty, we're just pushing the first FM.
* The tlp gets added when we push next time.
*
* PROMISES
*
* returns: rcSuccess
* rcOutOfMemory
* rcFailure - not properly initialized
*
* globals OUT: hstackBack - top element has valid ifm of current topic
* previous element has valid tlp of topic left
*
* Side Effects: uses FMT
*
\***************************************************************************/
RC STDCALL RcBackPush(BOOL fCtx, TLP tlpOld, CTX ctxOld, FM fmNew, int iWindow)
{
BSE bse;
bse.fCtx = (BOOL16) fCtx;
if (fCtx)
bse.ctx = ctxOld;
else
bse.tlp = tlpOld;
bse.ifm = (INT16) GetFmIndex(fmNew);
if (!bse.ifm)
return rcOutOfMemory;
RcPushStack(ahwnd[iWindow].hstackBack, &bse);
return rcSuccess;
}
/***************************************************************************\
*
- Function: FBackup()
-
* Purpose: Jump to the topic from the backup stack.
*
* ASSUMES
* globals IN: hstackBack
*
* PROMISES
* returns: TRUE on success; FALSE on failure (OOM)
* globals OUT: hstackBack - top of stack removed
* state OUT:
*
* Side Effects: if there was a location stored on stack, we've jumped there
*
* Note: Review: This should pass fm and tlp out as parameters and
* Review: return an rc so back can move to the layer. The
* Review: rc could be rcSuccess, rcNoExists, or rcOutOfMemory.
*
\***************************************************************************/
BOOL STDCALL FBackup(int iWindow)
{
BSE bseTop, bse;
FM fm;
TLPHELP tlphelp;
BOOL f; // return value
char szFile[MAX_PATH + cchWindowMemberMax];
// Can't pop unless there are 2 elements on the stack: current and old.
if (CElementsStack(ahwnd[iWindow].hstackBack) < 2)
return TRUE;
ENSURE(RcTopStack(ahwnd[iWindow].hstackBack, &bseTop), rcSuccess);
ENSURE(RcPopStack(ahwnd[iWindow].hstackBack), rcSuccess);
ENSURE(RcTopStack(ahwnd[iWindow].hstackBack, &bse), rcSuccess);
fBackMagic = TRUE;
// For context based backtrace, we need to ensure that the magic fcl is
// null so that the hack in JumpGeneric will continue to work.
if (bse.fCtx) {
tlpBackMagic.va.dword = 0;
tlpBackMagic.lScroll = 0;
}
else
tlpBackMagic = bseTop.tlp;
/*
* Note that we can tell if we're going to change files and wouldn't
* need to get the fm if we jumped with Goto() rather than FWinHelp().
*/
fm = GetFmPtr(bse.ifm);
if (!FExistFm(fm)) {
/*
* The old help file has disappeared somehow (e.g. network drive
* disconnected, CD removed from drive.)
*/
ErrorVarArgs(wERRS_NOTAVAILABLE, wERRA_RETURN, PszFromGh(fm));
/*
* While the user may be able to reconnect to the server, strange
* things can happen at this point -- i.e., the keyword list will be
* hosed. We'll play it safe and exit WinHelp.
*/
// REVIEW: not necessary if this is an interfile Back
CloseHelp();
return TRUE;
}
strcpy(szFile, fm);
strcat(szFile, ">");
strcat(szFile, ahwnd[iWindow].pszMemberName);
// REVIEW: We should change to GoTo() for same-file jumps
if (bse.fCtx) {
f = FWinHelp(szFile, HELP_CONTEXT, (LONG) bse.ctx);
}
else {
tlphelp.cb = sizeof(TLPHELP);
tlphelp.tlp = bseTop.tlp;
f = FWinHelp(szFile, cmdTLP, (LONG) (void*) &tlphelp);
}
if (!f) {
// The jump failed; put the bse back onto the stack.
// REVIEW: why put it back on the stack? It doesn't work, so why
// not toss it?
ASSERT(f); // so we can break into debugger and find out what to do
RcPushStack(ahwnd[iWindow].hstackBack, &bseTop);
fBackMagic = FALSE;
}
return f;
}
/***************************************************************************
FUNCTION: BackFlush
PURPOSE: Flush the back stack so the user can't go back
PARAMETERS:
void
RETURNS:
COMMENTS:
MODIFICATION DATES:
14-Jul-1994 [ralphw]
***************************************************************************/
void STDCALL BackFlush(void)
{
while (RcPopStack(ahwnd[iCurWindow].hstackBack) == rcSuccess);
}