|
|
//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1997 - 1999
//
// File: util.h
//
//--------------------------------------------------------------------------
#ifndef _UTIL_H_
#define _UTIL_H_
#ifndef _INC_CSCVIEW_CONFIG_H
# include "config.h"
#endif
#include "debug.h"
HRESULT GetRemotePath(LPCTSTR szInName, LPTSTR *pszOutName); LPTSTR ULongToString(ULONG i, LPTSTR psz, ULONG cchMax); VOID LocalFreeString(LPTSTR *ppsz); BOOL LocalAllocString(LPTSTR *ppszDest, LPCTSTR pszSrc); UINT SizeofStringResource(HINSTANCE hInstance, UINT idStr); int LoadStringAlloc(LPTSTR *ppszResult, HINSTANCE hInstance, UINT idStr); void ShellChangeNotify(LPCTSTR pszPath, WIN32_FIND_DATA *pfd, BOOL bFlush, LONG nEvent = 0); inline void ShellChangeNotify(LPCTSTR pszPath, BOOL bFlush = FALSE, LONG nEvent = 0) {ShellChangeNotify(pszPath, NULL, bFlush, nEvent);} HRESULT GetLinkTarget(LPCTSTR pszShortcut, LPTSTR *ppszTarget, DWORD *pdwAttr = NULL); void CenterWindow(HWND hwnd, HWND hwndParent); DWORD CSCUIRebootSystem(void); HRESULT SHSimpleIDListFromFindData(LPCTSTR pszPath, const WIN32_FIND_DATA *pfd, LPITEMIDLIST *ppidl); DWORD CscDelete(LPCTSTR pszPath); HRESULT IsOpenConnectionShare(LPCTSTR pszShare); BOOL IsCSCEnabled(void); BOOL IsCacheEncrypted(BOOL *pbPartial); BOOL IsSyncInProgress(void); BOOL IsPurgeInProgress(void); BOOL IsEncryptionInProgress(void); HANDLE RequestPermissionToEncryptCache(void); bool CscVolumeSupportsEncryption(LPCTSTR pszPath = NULL); BOOL IsWindowsTerminalServer(void); HRESULT SHCreateFileSysBindCtx(const WIN32_FIND_DATA *pfd, IBindCtx **ppbc); BOOL DeleteOfflineFilesFolderLink(HWND hwndParent = NULL); BOOL DeleteOfflineFilesFolderLink_PerfSensitive(HWND hwndParent = NULL); BOOL ShowHidden(void); BOOL ShowSuperHidden(void); BOOL IsSyncMgrInitialized(void); void SetSyncMgrInitialized(void); HWND GetProgressDialogWindow(IProgressDialog *ppd); HRESULT ExpandStringInPlace(LPTSTR psz, DWORD cch); LONG _RegEnumValueExp( HKEY hKey, DWORD dwIndex, LPTSTR lpValueName, LPDWORD lpcbValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData);
//
// Info returned through CSCFindFirst[Next]File APIs.
//
struct CscFindData { WIN32_FIND_DATA fd; DWORD dwStatus; DWORD dwPinCount; DWORD dwHintFlags; FILETIME ft; };
HANDLE CacheFindFirst(LPCTSTR pszPath, PSID psid, WIN32_FIND_DATA *pfd, DWORD *pdwStatus, DWORD *pdwPinCount, DWORD *pdwHintFlags, FILETIME *pft);
inline HANDLE CacheFindFirst(LPCTSTR pszPath, WIN32_FIND_DATA *pfd, DWORD *pdwStatus, DWORD *pdwPinCount, DWORD *pdwHintFlags, FILETIME *pft) { return CacheFindFirst(pszPath, (PSID)NULL, pfd, pdwStatus, pdwPinCount, pdwHintFlags, pft); }
inline HANDLE CacheFindFirst(LPCTSTR pszPath, CscFindData *p) { return CacheFindFirst(pszPath, &p->fd, &p->dwStatus, &p->dwPinCount, &p->dwHintFlags, &p->ft); }
inline HANDLE CacheFindFirst(LPCTSTR pszPath, PSID psid, CscFindData *p) { return CacheFindFirst(pszPath, psid, &p->fd, &p->dwStatus, &p->dwPinCount, &p->dwHintFlags, &p->ft); }
BOOL CacheFindNext(HANDLE hFind, WIN32_FIND_DATA *pfd, DWORD *pdwStatus, DWORD *pdwPinCount, DWORD *pdwHintFlags, FILETIME *pft);
inline BOOL CacheFindNext(HANDLE hFind, CscFindData *p) { return CacheFindNext(hFind, &p->fd, &p->dwStatus, &p->dwPinCount, &p->dwHintFlags, &p->ft); }
inline bool IsHiddenSystem(DWORD dwAttr) { return ((dwAttr & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) == (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)); }
inline BOOL _PathIsSlow(DWORD dwSpeed) { return (dwSpeed && dwSpeed <= DWORD(CConfig::GetSingleton().SlowLinkSpeed())); }
typedef struct { TCHAR szVolume[80]; // Volume where CSC cache is stored.
LONGLONG llBytesOnVolume; // Disk size (bytes)
LONGLONG llBytesTotalInCache; // Size of cache (bytes)
LONGLONG llBytesUsedInCache; // Amount of cache used (bytes)
DWORD dwNumFilesInCache; // Files in cache
DWORD dwNumDirsInCache; // Directories in cache
} CSCSPACEUSAGEINFO;
void GetCscSpaceUsageInfo(CSCSPACEUSAGEINFO *psui);
typedef enum _enum_reason { ENUM_REASON_FILE = 0, ENUM_REASON_FOLDER_BEGIN, ENUM_REASON_FOLDER_END } ENUM_REASON;
typedef DWORD (WINAPI *PFN_CSCENUMPROC)(LPCTSTR, ENUM_REASON, DWORD, DWORD, DWORD, PWIN32_FIND_DATA, LPARAM); DWORD _CSCEnumDatabase(LPCTSTR pszFolder, BOOL bRecurse, PFN_CSCENUMPROC pfnCB, LPARAM lpContext);
typedef DWORD (WINAPI *PFN_WIN32ENUMPROC)(LPCTSTR, ENUM_REASON, PWIN32_FIND_DATA, LPARAM); DWORD _Win32EnumFolder(LPCTSTR pszFolder, BOOL bRecurse, PFN_WIN32ENUMPROC pfnCB, LPARAM lpContext);
//
// Statistical information about a particular network share in the CSC database.
//
typedef struct _CSCSHARESTATS { int cTotal; int cPinned; int cModified; int cSparse; int cDirs; int cAccessUser; int cAccessGuest; int cAccessOther; bool bOffline; bool bOpenFiles; } CSCSHARESTATS, *PCSCSHARESTATS;
typedef struct { int cShares; int cTotal; int cPinned; int cModified; int cSparse; int cDirs; int cAccessUser; int cAccessGuest; int cAccessOther; int cSharesOffline; int cSharesWithOpenFiles; } CSCCACHESTATS, *PCSCCACHESTATS;
//
// These flags indicate if the enumeration should stop when one or more associated
// value's exceed 1. This is useful when you're interested in 0 vs. !0 as opposed
// to an actual count.
// If multiple flags are set, the statistics enumeration continues until the
// values corresponding to ALL set unity flags are non-zero.
//
enum SHARE_STATS_UNITY_FLAGS { SSUF_NONE = 0x00000000, // This is the default.
SSUF_TOTAL = 0x00000001, SSUF_PINNED = 0x00000002, SSUF_MODIFIED = 0x00000004, SSUF_SPARSE = 0x00000008, SSUF_DIRS = 0x00000010, SSUF_ACCUSER = 0x00000020, SSUF_ACCGUEST = 0x00000040, SSUF_ACCOTHER = 0x00000080, SSUF_ACCAND = 0x00000100, // Must match all set access mask flags.
SSUF_ACCOR = 0x00000200, // Match at least one access mask flag.
SSUF_ALL = 0x000000FF }; //
// These flags indicate if any cache items should be excluded from the enumeration.
// By default, the value is 0 (everything included). For perf reasons, we use the
// same flags defined in cscapi.h.
//
enum SHARE_STATS_EXCLUDE_FLAGS { SSEF_NONE = 0x00000000, // Default. Include everything.
SSEF_LOCAL_MOD_DATA = FLAG_CSC_COPY_STATUS_DATA_LOCALLY_MODIFIED, SSEF_LOCAL_MOD_ATTRIB = FLAG_CSC_COPY_STATUS_ATTRIB_LOCALLY_MODIFIED, SSEF_LOCAL_MOD_TIME = FLAG_CSC_COPY_STATUS_TIME_LOCALLY_MODIFIED, SSEF_LOCAL_DELETED = FLAG_CSC_COPY_STATUS_LOCALLY_DELETED, SSEF_LOCAL_CREATED = FLAG_CSC_COPY_STATUS_LOCALLY_CREATED, SSEF_STALE = FLAG_CSC_COPY_STATUS_STALE, SSEF_SPARSE = FLAG_CSC_COPY_STATUS_SPARSE, SSEF_ORPHAN = FLAG_CSC_COPY_STATUS_ORPHAN, SSEF_SUSPECT = FLAG_CSC_COPY_STATUS_SUSPECT, SSEF_CSCMASK = FLAG_CSC_COPY_STATUS_DATA_LOCALLY_MODIFIED | FLAG_CSC_COPY_STATUS_ATTRIB_LOCALLY_MODIFIED | FLAG_CSC_COPY_STATUS_TIME_LOCALLY_MODIFIED | FLAG_CSC_COPY_STATUS_LOCALLY_DELETED | FLAG_CSC_COPY_STATUS_LOCALLY_CREATED | FLAG_CSC_COPY_STATUS_STALE | FLAG_CSC_COPY_STATUS_SPARSE | FLAG_CSC_COPY_STATUS_ORPHAN | FLAG_CSC_COPY_STATUS_SUSPECT, SSEF_DIRECTORY = 0x01000000, SSEF_FILE = 0x02000000, SSEF_NOACCUSER = 0x04000000, // Exclude if no USER access.
SSEF_NOACCGUEST = 0x08000000, // Exclude if no GUEST access.
SSEF_NOACCOTHER = 0x10000000, // Exclude if no OTHER access.
SSEF_NOACCAND = 0x20000000 // Treat previous 3 flags as single mask.
};
typedef struct { DWORD dwExcludeFlags; // [in] SSEF_XXXXX flags.
DWORD dwUnityFlags; // [in] SSUF_XXXXX flags.
bool bAccessInfo; // [in] Implied 'T' if unity or exclude access bits are set.
bool bEnumAborted; // [out]
} CSCGETSTATSINFO, *PCSCGETSTATSINFO;
BOOL _GetShareStatistics(LPCTSTR pszShare, PCSCGETSTATSINFO pi, PCSCSHARESTATS pss); BOOL _GetCacheStatistics(PCSCGETSTATSINFO pi, PCSCCACHESTATS pcs); BOOL _GetShareStatisticsForUser(LPCTSTR pszShare, PCSCGETSTATSINFO pi, PCSCSHARESTATS pss); BOOL _GetCacheStatisticsForUser(PCSCGETSTATSINFO pi, PCSCCACHESTATS pcs);
// Higher level wrapper for IDA stuff
class CIDArray { private: STGMEDIUM m_Medium; LPIDA m_pIDA; IShellFolder *m_psf;
public: CIDArray() : m_pIDA(NULL), m_psf(NULL) { ZeroMemory(&m_Medium, sizeof(m_Medium)); }
~CIDArray();
HRESULT Initialize(IDataObject *pdobj);
HRESULT GetFolderPath(LPTSTR pszPath, UINT cch); HRESULT GetItemPath(UINT iItem, LPTSTR pszPath, UINT cch, DWORD *pdwAttribs); UINT Count() { return m_pIDA ? m_pIDA->cidl : 0; } };
//
// Trivial class to ensure cleanup of FindFirst/FindNext handles.
// Perf should be as close as possible to a simple handle so most
// operations are defined inline.
// Implementation is in enum.cpp
//
class CCscFindHandle { public: CCscFindHandle(HANDLE handle = INVALID_HANDLE_VALUE) : m_handle(handle), m_bOwns(INVALID_HANDLE_VALUE != handle) { }
CCscFindHandle(const CCscFindHandle& rhs) : m_handle(INVALID_HANDLE_VALUE), m_bOwns(false) { *this = rhs; }
~CCscFindHandle(void) { Close(); }
void Close(void);
HANDLE Detach(void) const { m_bOwns = false; return m_handle; }
void Attach(HANDLE handle) { Close(); m_handle = handle; m_bOwns = true; }
operator HANDLE() const { return m_handle; }
bool IsValid(void) const { return INVALID_HANDLE_VALUE != m_handle; }
CCscFindHandle& operator = (HANDLE handle) { Attach(handle); return *this; }
CCscFindHandle& operator = (const CCscFindHandle& rhs);
private: mutable HANDLE m_handle; mutable bool m_bOwns; };
class CMutexAutoRelease { public: explicit CMutexAutoRelease(HANDLE hmutex) : m_hmutex(hmutex) { }
~CMutexAutoRelease(void) { if (m_hmutex) { ReleaseMutex(m_hmutex); CloseHandle(m_hmutex); } }
private: HANDLE m_hmutex;
CMutexAutoRelease(const CMutexAutoRelease& rhs); CMutexAutoRelease& operator = (const CMutexAutoRelease& rhs); };
//
// Ensures CoInitialize/CoUninitialize is exception-safe.
//
class CCoInit { public: CCoInit(void) : m_hr(CoInitialize(NULL)) { }
~CCoInit(void) { if (SUCCEEDED(m_hr)) CoUninitialize(); }
HRESULT Result(void) const { return m_hr; } private: HRESULT m_hr; };
// String formatting functions - *ppszResult must be LocalFree'd
DWORD FormatStringID(LPTSTR *ppszResult, HINSTANCE hInstance, UINT idStr, ...); DWORD FormatString(LPTSTR *ppszResult, LPCTSTR pszFormat, ...); DWORD FormatSystemError(LPTSTR *ppszResult, DWORD dwSysError); DWORD vFormatStringID(LPTSTR *ppszResult, HINSTANCE hInstance, UINT idStr, va_list *pargs); DWORD vFormatString(LPTSTR *ppszResult, LPCTSTR pszFormat, va_list *pargs);
void EnableDlgItems(HWND hwndDlg, const UINT* pCtlIds, int cCtls, bool bEnable); void ShowDlgItems(HWND hwndDlg, const UINT* pCtlIds, int cCtls, bool bShow);
//
// We commonly use groups of CSC status flags together.
// Define them here so we're consistent throughout the project.
//
#define FLAG_CSCUI_COPY_STATUS_LOCALLY_DIRTY (FLAG_CSC_COPY_STATUS_DATA_LOCALLY_MODIFIED | \
FLAG_CSC_COPY_STATUS_LOCALLY_DELETED | \ FLAG_CSC_COPY_STATUS_LOCALLY_CREATED)
#define FLAG_CSCUI_COPY_STATUS_ALL_DIRTY (FLAG_CSC_COPY_STATUS_DATA_LOCALLY_MODIFIED | \
FLAG_CSC_COPY_STATUS_ATTRIB_LOCALLY_MODIFIED | \ FLAG_CSC_COPY_STATUS_TIME_LOCALLY_MODIFIED | \ FLAG_CSC_COPY_STATUS_LOCALLY_DELETED | \ FLAG_CSC_COPY_STATUS_LOCALLY_CREATED)
//
// Some helper inlines for querying cache item access information.
//
inline bool CscCheckAccess(DWORD dwShareStatus, DWORD dwShift, DWORD dwAccessType) { return 0 != ((dwShareStatus >> dwShift) & dwAccessType); }
inline bool CscAccessUserRead(DWORD dwShareStatus) { return CscCheckAccess(dwShareStatus, FLAG_CSC_USER_ACCESS_SHIFT_COUNT, FLAG_CSC_READ_ACCESS); }
inline bool CscAccessUserWrite(DWORD dwShareStatus) { return CscCheckAccess(dwShareStatus, FLAG_CSC_USER_ACCESS_SHIFT_COUNT, FLAG_CSC_WRITE_ACCESS); }
inline bool CscAccessUser(DWORD dwShareStatus) { return 0 != (dwShareStatus & FLAG_CSC_USER_ACCESS_MASK); }
inline bool CscAccessGuestRead(DWORD dwShareStatus) { return CscCheckAccess(dwShareStatus, FLAG_CSC_GUEST_ACCESS_SHIFT_COUNT, FLAG_CSC_READ_ACCESS); }
inline bool CscAccessGuestWrite(DWORD dwShareStatus) { return CscCheckAccess(dwShareStatus, FLAG_CSC_GUEST_ACCESS_SHIFT_COUNT, FLAG_CSC_WRITE_ACCESS); }
inline bool CscAccessGuest(DWORD dwShareStatus) { return 0 != (dwShareStatus & FLAG_CSC_GUEST_ACCESS_MASK); }
inline bool CscAccessOtherRead(DWORD dwShareStatus) { return CscCheckAccess(dwShareStatus, FLAG_CSC_OTHER_ACCESS_SHIFT_COUNT, FLAG_CSC_READ_ACCESS); }
inline bool CscAccessOtherWrite(DWORD dwShareStatus) { return CscCheckAccess(dwShareStatus, FLAG_CSC_OTHER_ACCESS_SHIFT_COUNT, FLAG_CSC_WRITE_ACCESS); }
inline bool CscAccessOther(DWORD dwShareStatus) { return 0 != (dwShareStatus & FLAG_CSC_OTHER_ACCESS_MASK); }
inline bool CscCanUserMergeFile(DWORD dwStatus) { return (CscAccessUserWrite(dwStatus) || CscAccessGuestWrite(dwStatus)); }
//
// template inlines avoid the side-effects of min/max macros.
//
template <class T> inline const T& MAX(const T& a, const T& b) { return a > b ? a : b; }
template <class T> inline const T& MIN(const T& a, const T& b) { return a < b ? a : b; }
class CWin32Handle { public: CWin32Handle(HANDLE handle) : m_handle(handle) { }
CWin32Handle(void) : m_handle(NULL) { }
~CWin32Handle(void) { Close(); }
void Close(void) { if (m_handle) CloseHandle(m_handle); m_handle = NULL; }
operator HANDLE() const { return m_handle; }
HANDLE *HandlePtr(void) { TraceAssert((NULL == m_handle)); return &m_handle; }
private: HANDLE m_handle;
//
// Prevent copy.
// This class is only intended for automatic handle cleanup.
//
CWin32Handle(const CWin32Handle& rhs); CWin32Handle& operator = (const CWin32Handle& rhs); };
HRESULT DataObject_SetGlobal(IDataObject *pdtobj, CLIPFORMAT cf, HGLOBAL hGlobal); HRESULT DataObject_SetDWORD(IDataObject *pdtobj, CLIPFORMAT cf, DWORD dw); HRESULT DataObject_GetDWORD(IDataObject *pdtobj, CLIPFORMAT cf, DWORD *pdwOut); HRESULT SetPreferredDropEffect(IDataObject *pdtobj, DWORD dwEffect); DWORD GetPreferredDropEffect(IDataObject *pdtobj); HRESULT SetLogicalPerformedDropEffect(IDataObject *pdtobj, DWORD dwEffect); DWORD GetLogicalPerformedDropEffect(IDataObject *pdtobj);
//
// Simple class for automating the display and resetting of a wait cursor.
//
class CAutoWaitCursor { public: CAutoWaitCursor(void) : m_hCursor(SetCursor(LoadCursor(NULL, IDC_WAIT))) { ShowCursor(TRUE); }
~CAutoWaitCursor(void) { Reset(); }
void Reset(void);
private: HCURSOR m_hCursor; };
class CAutoSetRedraw { public: CAutoSetRedraw(HWND hwnd) : m_hwnd(hwnd) { }
CAutoSetRedraw(HWND hwnd, bool bSet) : m_hwnd(hwnd) { Set(bSet); }
~CAutoSetRedraw(void) { Set(true); }
void Set(bool bSet) { SendMessage(m_hwnd, WM_SETREDRAW, (WPARAM)bSet, 0); }
private: HWND m_hwnd; };
#endif // _UTIL_H_
|