227 lines
4.2 KiB
C
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;
|
||
|
}
|
||
|
|