windows-nt/Source/XPSP1/NT/shell/ext/docprop/propmisc.c
2020-09-26 16:20:57 +08:00

257 lines
5.2 KiB
C

////////////////////////////////////////////////////////////////////////////////
//
// propmisc.c
//
// Misc. Property set rotuines
//
// Change history:
//
// Date Who What
// --------------------------------------------------------------------------
// 07/30/94 B. Wentz Created file
//
////////////////////////////////////////////////////////////////////////////////
#include "priv.h"
#pragma hdrstop
////////////////////////////////////////////////////////////////////////////////
//
// LpllCreateList
//
// Purpose:
// Create a linked list with dwc elements.
//
////////////////////////////////////////////////////////////////////////////////
LPLLIST
LpllCreate
(LPLLIST *lplpll, // Head
LPLLCACHE lpllcache, // Cache
DWORD dwc, // Number of nodes to create
DWORD cbNode) // Size of each node
{
LPLLIST lpllT;
LPLLIST lpllCur;
if ((lplpll == NULL) ||
(dwc < 1) ||
(cbNode < sizeof(LLIST)))
return NULL;
lpllCur = *lplpll = PvMemAlloc(cbNode);
if (lpllCur == NULL)
{
return NULL;
}
FillBuf (lpllCur, 0, cbNode);
lpllCur->lpllistPrev = NULL;
dwc--;
while (dwc)
{
lpllT = PvMemAlloc(cbNode);
if (lpllT == NULL)
goto Fail;
FillBuf (lpllT, 0, cbNode);
lpllT->lpllistPrev = lpllCur;
lpllCur->lpllistNext = lpllT;
lpllCur = lpllT;
dwc--;
} // while
lpllCur->lpllistNext = NULL;
lpllcache->lpllist = NULL;
return *lplpll;
Fail :
lpllCur = *lplpll;
while (lpllCur != NULL)
{
lpllT = lpllCur;
lpllCur = lpllCur->lpllistNext;
VFreeMemP(lpllT, cbNode);
}
return NULL;
} // LpllCreateList
////////////////////////////////////////////////////////////////////////////////
//
// LpllGetNode
//
// Purpose:
// Gets a node from the list
//
////////////////////////////////////////////////////////////////////////////////
LPLLIST
LpllGetNode
(LPLLIST lpllist, // The head
LPLLCACHE lpllcache, // The cache
DWORD idw) // Index of node to get -- 1 based
{
DWORD i = idw;
if ((lpllcache->lpllist != NULL) && (lpllcache->idw == idw))
{
return lpllcache->lpllist;
}
while ((i > 1) && (lpllist != NULL))
{
lpllist = lpllist->lpllistNext;
i--;
}
if (lpllist != NULL)
{
lpllcache->idw = idw;
lpllcache->lpllist = lpllist;
}
return lpllist;
} // LpllGetNode
////////////////////////////////////////////////////////////////////////////////
//
// LpllDeleteNode
//
// Purpose:
// Delete a node from the list
//
////////////////////////////////////////////////////////////////////////////////
LPLLIST
LpllDeleteNode
(LPLLIST lpllist, // Head
LPLLCACHE lpllcache, // Cache
DWORD idw, // Index -- 1 based
DWORD cbNode, // Size of node
void (*lpfnFreeNode)(LPLLIST) // Free a node
)
{
LPLLIST lpT;
LPLLIST lpNext;
BOOL fHead;
// Check the cache
if ((lpllcache->lpllist != NULL) && (lpllcache->idw == idw))
{
lpT = lpllcache->lpllist;
lpllcache->lpllist = NULL;
}
else
{
lpT = LpllGetNode (lpllist, lpllcache, idw);
}
if (lpT == NULL) // We couldn't find the node
{
return lpT;
}
fHead = lpT->lpllistPrev == NULL;
// Delete the node from the list
if (lpT->lpllistPrev != NULL)
{
lpT->lpllistPrev->lpllistNext = lpT->lpllistNext;
}
if ((lpNext = lpT->lpllistNext) != NULL)
{
lpT->lpllistNext->lpllistPrev = lpT->lpllistPrev;
}
// Delete the string & node
(*lpfnFreeNode) (lpT);
VFreeMemP(lpT, cbNode);
// If the head was deleted, return the new one.
return (fHead ? lpNext : lpllist);
} // LpllDeleteNode
////////////////////////////////////////////////////////////////////////////////
//
// LpllInsertNode
//
// Purpose:
// Insert a node into the list
//
////////////////////////////////////////////////////////////////////////////////
LPLLIST PASCAL
LpllInsertNode
(LPLLIST lpllist, // Head
LPLLCACHE lpllcache, // Cache
DWORD idw, // index
DWORD cbNode) // Size of node
{
LPLLIST lpT;
LPLLIST lpOrigHead;
BOOL fHead;
DWORD idwOrig;
if ((lpOrigHead = lpllist) == NULL)
{
return NULL;
}
idwOrig = idw;
Assert ((idw > 0));
idw--;
while ((idw) && (lpllist->lpllistNext != NULL))
{
lpllist = lpllist->lpllistNext;
idw--;
}
lpT = PvMemAlloc(cbNode);
if (lpT == NULL)
{
return NULL;
}
FillBuf (lpT, 0, cbNode);
// If the new node was to be inserted at the end, idw would not
// be zero, the while loop would have fallen out because Next was NULL
if (idw)
{
fHead = FALSE;
lpT->lpllistPrev = lpllist;
lpT->lpllistNext = NULL;
lpllist->lpllistNext = lpT;
}
else
{
fHead = (lpllist == lpOrigHead);
lpT->lpllistPrev = lpllist->lpllistPrev;
if (lpllist->lpllistPrev != NULL)
{
lpllist->lpllistPrev->lpllistNext = lpT;
}
lpT->lpllistNext = lpllist;
lpllist->lpllistPrev = lpT;
}
// Update the cache
lpllcache->idw = idwOrig;
lpllcache->lpllist = lpT;
return (fHead ? lpT : lpOrigHead);
} // LpllInsertNode