//--------------------------------------------------------------------------- // // Copyright (c) Microsoft Corporation 1993-1994 // // File: cpath.c // // This files contains code for the cached briefcase paths. // // History: // 01-31-94 ScottH Created // //--------------------------------------------------------------------------- ///////////////////////////////////////////////////// INCLUDES #include "brfprv.h" // common headers CACHE g_cacheCPATH = {0, 0, 0}; // Briefcase path cache #define CPATH_EnterCS() EnterCriticalSection(&g_cacheCPATH.cs) #define CPATH_LeaveCS() LeaveCriticalSection(&g_cacheCPATH.cs) #ifdef DEBUG /*---------------------------------------------------------- Purpose: Dumps a CPATH entry Returns: Cond: -- */ void PRIVATE CPATH_DumpEntry( CPATH * pcpath) { ASSERT(pcpath); TRACE_MSG(TF_ALWAYS, TEXT("CPATH: Atom %d: %s"), pcpath->atomPath, Atom_GetName(pcpath->atomPath)); TRACE_MSG(TF_ALWAYS, TEXT(" Ref [%u] "), Cache_GetRefCount(&g_cacheCPATH, pcpath->atomPath)); } /*---------------------------------------------------------- Purpose: Dumps all CPATH cache Returns: Cond: -- */ void PUBLIC CPATH_DumpAll() { CPATH * pcpath; int atom; BOOL bDump; ENTEREXCLUSIVE() { bDump = IsFlagSet(g_uDumpFlags, DF_CPATH); } LEAVEEXCLUSIVE() if (!bDump) return ; atom = Cache_FindFirstKey(&g_cacheCPATH); while (atom != ATOM_ERR) { pcpath = Cache_GetPtr(&g_cacheCPATH, atom); ASSERT(pcpath); if (pcpath) { CPATH_DumpEntry(pcpath); Cache_DeleteItem(&g_cacheCPATH, atom, FALSE, NULL, CPATH_Free); // Decrement count } atom = Cache_FindNextKey(&g_cacheCPATH, atom); } } #endif /*---------------------------------------------------------- Purpose: Release the volume ID handle Returns: -- Cond: hwndOwner is not used. This function is serialized by the caller (Cache_Term or Cache_DeleteItem). */ void CALLBACK CPATH_Free( LPVOID lpv, HWND hwndOwner) { CPATH * pcpath = (CPATH *)lpv; DEBUG_CODE( TRACE_MSG(TF_CACHE, TEXT("CPATH Freeing Briefcase path %s"), Atom_GetName(pcpath->atomPath)); ) // Delete the atom one extra time, because we explicitly added // it for this cache. Atom_Delete(pcpath->atomPath); SharedFree(&pcpath); } /*---------------------------------------------------------- Purpose: Add the atomPath to the cache. If atomPath is already in the cache, we replace it with a newly obtained path. Returns: Pointer to CPATH NULL on OOM Cond: -- */ CPATH * PUBLIC CPATH_Replace( int atomPath) { CPATH * pcpath; BOOL bJustAllocd; CPATH_EnterCS(); { pcpath = Cache_GetPtr(&g_cacheCPATH, atomPath); if (pcpath) bJustAllocd = FALSE; else { // Allocate using commctrl's Alloc, so the structure will be in // shared heap space across processes. pcpath = SharedAllocType(CPATH); bJustAllocd = TRUE; } if (pcpath) { LPCTSTR pszPath = Atom_GetName(atomPath); ASSERT(pszPath); DEBUG_CODE( TRACE_MSG(TF_CACHE, TEXT("CPATH Adding known Briefcase %s"), pszPath); ) pcpath->atomPath = atomPath; if (bJustAllocd) { if (!Cache_AddItem(&g_cacheCPATH, atomPath, (LPVOID)pcpath)) { // Cache_AddItem failed here // SharedFree(&pcpath); } } else Cache_DeleteItem(&g_cacheCPATH, atomPath, FALSE, NULL, CPATH_Free); // Decrement count } } CPATH_LeaveCS(); return pcpath; } /*---------------------------------------------------------- Purpose: Search for the given path in the cache. If the path exists, its locality will be returned. If it is not found, its locality is not known (but PL_FALSE is returned). Returns: path locality (PL_) value Cond: -- */ UINT PUBLIC CPATH_GetLocality( LPCTSTR pszPath, LPTSTR pszBuf) // Can be NULL, or must be MAXPATHLEN { UINT uRet = PL_FALSE; LPCTSTR pszBrf; int atom; ASSERT(pszPath); CPATH_EnterCS(); { atom = Cache_FindFirstKey(&g_cacheCPATH); while (atom != ATOM_ERR) { pszBrf = Atom_GetName(atom); ASSERT(pszBrf); if (IsSzEqual(pszBrf, pszPath)) { uRet = PL_ROOT; break; } else if (PathIsPrefix(pszBrf, pszPath)) { uRet = PL_INSIDE; break; } atom = Cache_FindNextKey(&g_cacheCPATH, atom); } if (uRet != PL_FALSE && pszBuf) lstrcpy(pszBuf, pszBrf); } CPATH_LeaveCS(); return uRet; }