Windows2000/private/shell/shell32/ynlist.c
2020-09-30 17:12:32 +02:00

226 lines
3.9 KiB
C

#include "shellprv.h"
#define YNLIST_ALLOC (2 * MAX_PATH * sizeof(TCHAR))
// Constructor - creates a YesNoList
void CreateYesNoList(PYNLIST pynl)
{
ZeroMemory(pynl, sizeof(*pynl));
}
// Destructor - frees and destroys a YesNoList
void DestroyYesNoList(PYNLIST pynl)
{
if (pynl->dlYes.pszzList)
GlobalFree(pynl->dlYes.pszzList);
if (pynl->dlNo.pszzList)
GlobalFree(pynl->dlNo.pszzList);
ZeroMemory(pynl, sizeof(*pynl));
}
// IsPathOfItem - determine if pszPath is on the path to pszItem
BOOL IsPathOfItem(LPCTSTR pszPath, LPCTSTR pszItem)
{
// Validate pszPath is the first
// substring of pszItem.
while (*pszPath)
{
if (*pszPath != *pszItem)
{
return FALSE;
}
pszPath++;
pszItem++;
}
// pszPath is the path if pszItem is empty (exact match),
// or pszItem is a directory separator.
return (*pszItem == TEXT('\\')) || (*pszItem == TEXT('\0'));
}
// IsInDirList - determines if DIRLIST contains
// the path to pszItem.
BOOL IsInDirList(PDIRLIST pdl, LPCTSTR pszItem)
{
LPTSTR pszzList;
// Quick check for everything flag.
if (pdl->fEverythingInList)
return TRUE;
// Quick check for empty list.
if (pdl->pszzList == NULL)
{
return FALSE;
}
// Compare against each string in the szz list.
pszzList = pdl->pszzList;
while (*pszzList)
{
// If pszList is the beginning of the path to pszItem,
// the item is in the list.
if (IsPathOfItem(pszzList, pszItem))
{
return TRUE;
}
pszzList += lstrlen(pszzList) + 1;
}
// Couldn't find it.
return FALSE;
}
// IsInYesList - determine if an item is in the
// yes list of a YesNoList.
BOOL IsInYesList(PYNLIST pynl, LPCTSTR pszItem)
{
// Call helper function.
return IsInDirList(&pynl->dlYes, pszItem);
}
// IsInNoList - determine if an item is in the
// no list of a YesNoList.
BOOL IsInNoList(PYNLIST pynl, LPCTSTR pszItem)
{
// Call helper function.
return IsInDirList(&pynl->dlNo, pszItem);
}
// AddToDirList - adds an item to a dir list if necessary.
void AddToDirList(PDIRLIST pdl, LPCTSTR pszItem)
{
UINT cchItem;
// Is the item already in the list?
if (IsInDirList(pdl, pszItem))
{
return;
}
// Is the list empty?
if (pdl->pszzList == NULL)
{
pdl->pszzList = (LPTSTR)GlobalAlloc(GPTR, YNLIST_ALLOC);
if (pdl->pszzList == NULL)
{
return;
}
pdl->cbAlloc = YNLIST_ALLOC;
pdl->cchUsed = 1;
ASSERT(pdl->pszzList[0] == TEXT('\0'));
}
// Get the string length,
// verify it can be added with
// at most one additional alloc.
cchItem = lstrlen(pszItem) + 1;
if (CbFromCch(cchItem) >= YNLIST_ALLOC)
{
return;
}
// Do we need to allocate more space?
if (CbFromCch(cchItem) > pdl->cbAlloc - CbFromCch(pdl->cchUsed))
{
LPTSTR pszzNew;
pszzNew = (LPTSTR)GlobalReAlloc(pdl->pszzList, pdl->cbAlloc + YNLIST_ALLOC, GMEM_MOVEABLE|GMEM_ZEROINIT);
if (pszzNew == NULL)
{
return;
}
pdl->pszzList = pszzNew;
pdl->cbAlloc += YNLIST_ALLOC;
}
// Add the item.
lstrcpy(&(pdl->pszzList[pdl->cchUsed - 1]), pszItem);
pdl->cchUsed += cchItem;
// Add the second NULL terminator
// (GlobalReAlloc can't guarantee zeromeminit)
pdl->pszzList[pdl->cchUsed - 1] = TEXT('\0');
}
// Adds an item to the Yes list.
void AddToYesList(PYNLIST pynl, LPCTSTR pszItem)
{
// Call helper function.
AddToDirList(&pynl->dlYes, pszItem);
}
// Adds an item to the No list.
void AddToNoList(PYNLIST pynl, LPCTSTR pszItem)
{
// Call helper function.
AddToDirList(&pynl->dlNo, pszItem);
}
// SetYesToAll - puts everything in the yes list.
void SetYesToAll(PYNLIST pynl)
{
pynl->dlYes.fEverythingInList = TRUE;
}