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.
 
 
 
 
 
 

268 lines
5.7 KiB

/*****************************************************************************
* *
* FMT.C *
* *
* Copyright (C) Microsoft Corporation 1990. *
* All Rights reserved. *
* *
******************************************************************************
* *
* Module Intent *
* FM caching module. Used in history and back lists. *
* *
* Currently, I don't keep a ref count of the FMs in the cache. This *
* means I can't shrink the cache until all users finish using it. *
* *
*****************************************************************************/
#include "help.h"
#pragma hdrstop
_subsystem( FMT );
/*****************************************************************************
* *
* Defines *
* *
*****************************************************************************/
/*****************************************************************************
* *
* Typedefs *
* *
*****************************************************************************/
/*****************************************************************************
* *
* Static Variables *
* *
*****************************************************************************/
/****************************************************************************\
*
* The following static variables define the cache. There is only one
* cache because the whole idea is to share it.
*
\****************************************************************************/
static INT16 cfm = 0; // count of FDs
static GH hrgfm = NULL; // handle to array of FDs
static FM * rgfm = NULL; // locked hrgfd (sometimes valid)
static INT16 cRefFmt = 0; // FDT ref count
/*****************************************************************************
* *
* Prototypes *
* *
*****************************************************************************/
/***************************************************************************\
*
- Function: RcInitFmt()
-
* Purpose: Enlist as a user of the FMT.
*
* ASSUMES
*
* globals IN: cRefFmt
*
* PROMISES
*
* returns: rcSuccess always
*
* globals OUT: ref count cRefFmt is incremented
*
* Note: If you RcInitFmt(), you must RcFiniFmt() when you're done.
*
* +++
*
* Method: Increment the ref count.
*
\***************************************************************************/
void STDCALL RcInitFmt()
{
++cRefFmt;
}
/***************************************************************************\
*
- Function: RcFiniFmt()
-
* Purpose: Tell the FMT you're done using it. When the last user
* finishes, memory is deallocated.
*
* ASSUMES
*
* PROMISES
*
* returns: rcSuccess rcFailure
*
\***************************************************************************/
void STDCALL RcFiniFmt(void)
{
INT16 ifm;
FM * qfmT;
ASSERT( 0 < cRefFmt );
if (0 == --cRefFmt) {
if (!hrgfm) {
if (rgfm == NULL)
rgfm = PtrFromGh(hrgfm);
for (ifm = 0, qfmT = rgfm; ifm < cfm; ++ifm, ++qfmT)
DisposeFm(*qfmT);
rgfm = NULL;
FreeGh(hrgfm);
hrgfm = NULL;
}
cfm = 0;
}
}
/***************************************************************************\
*
- Function: UnlockFmt()
-
* Purpose: Ensure that the FMT is unlocked.
*
* ASSUMES
*
* globals IN:
*
* PROMISES
*
* globals OUT:
*
* Notes: You should do this after performing the mapping functions
* before yielding.
*
* +++
*
* Method:
*
* Notes:
*
\***************************************************************************/
_public void STDCALL
UnlockFmt()
{
if (rgfm) {
ASSERT(NULL != hrgfm);
rgfm = NULL;
}
}
/***************************************************************************\
-
- Function: IfmFromFm( fm )
-
* Purpose: Map an ifm into an fm
*
* ASSUMES
*
* args IN: fm - map it to an ifm
*
* globals IN: rgfm
* hrgfm
*
* PROMISES
*
* returns: success - valid ifm
* failure - ifmNil
*
* globals OUT: hrgfm - array of saved FMs can grow
* rgfm - guaranteed to be hrgfm, locked
* cfm - can be incremented
*
* state OUT: FMT is locked
*
\***************************************************************************/
_public INT16 STDCALL
IfmFromFm( fm )
FM fm;
{
INT16 ifm;
FM fmT;
FM * qfmT;
GH ghT;
if (!rgfm) {
if (!hrgfm) {
if (!(hrgfm = GhAlloc(GPTR, sizeof(FM))))
return ifmNil;
cfm = 1;
rgfm = PtrFromGh( hrgfm );
ASSERT(NULL != rgfm);
ifm = 0;
fmT = FmCopyFm(fm);
rgfm[ ifm ] = fmT;
return ifm;
}
rgfm = PtrFromGh(hrgfm);
ASSERT(NULL != rgfm);
}
for (ifm = 0, qfmT = rgfm; ifm < cfm; ++ifm, ++qfmT) {
if (FSameFmFm(fm, *qfmT)) {
return ifm;
}
}
ghT = GhResize(hrgfm, 0, sizeof(FM) * ++cfm);
if ( NULL == ghT )
{
--cfm;
return ifmNil;
}
hrgfm = ghT;
rgfm = PtrFromGh( hrgfm );
fmT = FmCopyFm(fm);
rgfm[ ifm ] = fmT;
return ifm;
}
/***************************************************************************\
-
- Function: FmFromIfm( ifm )
-
* Purpose: Map an ifm into an fm.
*
* ASSUMES
*
* args IN: ifm - in range: 0 <= ifm < cfm
*
* globals IN:
*
* PROMISES
*
* returns: success: fm - a copy of the fm in the table (so it can be
* disposed without causing problems.
* failure: NULL
*
* state OUT: FMT is locked
*
\***************************************************************************/
FM STDCALL FmFromIfm(INT16 ifm)
{
if ( 0 > ifm || ifm >= cfm )
return NULL;
if (NULL == rgfm) {
ASSERT(NULL != hrgfm);
rgfm = PtrFromGh(hrgfm);
ASSERT(NULL != rgfm);
}
return rgfm[ ifm ];
}
/* EOF */