#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. // // Enough memory is allocated above that there is no need for bounded // copy 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; }