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

227 lines
4.2 KiB
C

#include "shellprv.h"
#include "ynlist.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;
}