Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

522 lines
17 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997 - 1999
  6. //
  7. // File: util.h
  8. //
  9. //--------------------------------------------------------------------------
  10. #ifndef _UTIL_H_
  11. #define _UTIL_H_
  12. #ifndef _INC_CSCVIEW_CONFIG_H
  13. # include "config.h"
  14. #endif
  15. #include "debug.h"
  16. HRESULT GetRemotePath(LPCTSTR szInName, LPTSTR *pszOutName);
  17. LPTSTR ULongToString(ULONG i, LPTSTR psz, ULONG cchMax);
  18. VOID LocalFreeString(LPTSTR *ppsz);
  19. BOOL LocalAllocString(LPTSTR *ppszDest, LPCTSTR pszSrc);
  20. UINT SizeofStringResource(HINSTANCE hInstance, UINT idStr);
  21. int LoadStringAlloc(LPTSTR *ppszResult, HINSTANCE hInstance, UINT idStr);
  22. void ShellChangeNotify(LPCTSTR pszPath, WIN32_FIND_DATA *pfd, BOOL bFlush, LONG nEvent = 0);
  23. inline void ShellChangeNotify(LPCTSTR pszPath, BOOL bFlush = FALSE, LONG nEvent = 0) {ShellChangeNotify(pszPath, NULL, bFlush, nEvent);}
  24. HRESULT GetLinkTarget(LPCTSTR pszShortcut, LPTSTR *ppszTarget, DWORD *pdwAttr = NULL);
  25. void CenterWindow(HWND hwnd, HWND hwndParent);
  26. DWORD CSCUIRebootSystem(void);
  27. HRESULT SHSimpleIDListFromFindData(LPCTSTR pszPath, const WIN32_FIND_DATA *pfd, LPITEMIDLIST *ppidl);
  28. DWORD CscDelete(LPCTSTR pszPath);
  29. HRESULT IsOpenConnectionShare(LPCTSTR pszShare);
  30. HRESULT IsOpenConnectionPathUNC(LPCTSTR pszPathUNC);
  31. BOOL IsCSCEnabled(void);
  32. BOOL IsCacheEncrypted(BOOL *pbPartial);
  33. BOOL IsSyncInProgress(void);
  34. BOOL IsPurgeInProgress(void);
  35. BOOL IsEncryptionInProgress(void);
  36. HANDLE RequestPermissionToEncryptCache(void);
  37. bool CscVolumeSupportsEncryption(LPCTSTR pszPath = NULL);
  38. BOOL IsWindowsTerminalServer(void);
  39. HRESULT SHCreateFileSysBindCtx(const WIN32_FIND_DATA *pfd, IBindCtx **ppbc);
  40. BOOL DeleteOfflineFilesFolderLink(HWND hwndParent = NULL);
  41. BOOL DeleteOfflineFilesFolderLink_PerfSensitive(HWND hwndParent = NULL);
  42. BOOL ShowHidden(void);
  43. BOOL ShowSuperHidden(void);
  44. BOOL IsSyncMgrInitialized(void);
  45. void SetSyncMgrInitialized(void);
  46. HWND GetProgressDialogWindow(IProgressDialog *ppd);
  47. HRESULT ExpandStringInPlace(LPTSTR psz, DWORD cch);
  48. //
  49. // Info returned through CSCFindFirst[Next]File APIs.
  50. //
  51. struct CscFindData
  52. {
  53. WIN32_FIND_DATA fd;
  54. DWORD dwStatus;
  55. DWORD dwPinCount;
  56. DWORD dwHintFlags;
  57. FILETIME ft;
  58. };
  59. HANDLE CacheFindFirst(LPCTSTR pszPath, PSID psid, WIN32_FIND_DATA *pfd, DWORD *pdwStatus, DWORD *pdwPinCount, DWORD *pdwHintFlags, FILETIME *pft);
  60. inline
  61. HANDLE CacheFindFirst(LPCTSTR pszPath, WIN32_FIND_DATA *pfd, DWORD *pdwStatus, DWORD *pdwPinCount, DWORD *pdwHintFlags, FILETIME *pft)
  62. { return CacheFindFirst(pszPath, (PSID)NULL, pfd, pdwStatus, pdwPinCount, pdwHintFlags, pft); }
  63. inline
  64. HANDLE CacheFindFirst(LPCTSTR pszPath, CscFindData *p)
  65. { return CacheFindFirst(pszPath, &p->fd, &p->dwStatus, &p->dwPinCount, &p->dwHintFlags, &p->ft); }
  66. inline
  67. HANDLE CacheFindFirst(LPCTSTR pszPath, PSID psid, CscFindData *p)
  68. { return CacheFindFirst(pszPath, psid, &p->fd, &p->dwStatus, &p->dwPinCount, &p->dwHintFlags, &p->ft); }
  69. BOOL CacheFindNext(HANDLE hFind, WIN32_FIND_DATA *pfd, DWORD *pdwStatus, DWORD *pdwPinCount, DWORD *pdwHintFlags, FILETIME *pft);
  70. inline
  71. BOOL CacheFindNext(HANDLE hFind, CscFindData *p)
  72. { return CacheFindNext(hFind, &p->fd, &p->dwStatus, &p->dwPinCount, &p->dwHintFlags, &p->ft); }
  73. inline bool IsHiddenSystem(DWORD dwAttr)
  74. {
  75. return ((dwAttr & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM)) == (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM));
  76. }
  77. inline BOOL _PathIsSlow(DWORD dwSpeed) { return (dwSpeed && dwSpeed <= DWORD(CConfig::GetSingleton().SlowLinkSpeed())); }
  78. typedef struct
  79. {
  80. TCHAR szVolume[80]; // Volume where CSC cache is stored.
  81. LONGLONG llBytesOnVolume; // Disk size (bytes)
  82. LONGLONG llBytesTotalInCache; // Size of cache (bytes)
  83. LONGLONG llBytesUsedInCache; // Amount of cache used (bytes)
  84. DWORD dwNumFilesInCache; // Files in cache
  85. DWORD dwNumDirsInCache; // Directories in cache
  86. } CSCSPACEUSAGEINFO;
  87. void GetCscSpaceUsageInfo(CSCSPACEUSAGEINFO *psui);
  88. typedef enum _enum_reason
  89. {
  90. ENUM_REASON_FILE = 0,
  91. ENUM_REASON_FOLDER_BEGIN,
  92. ENUM_REASON_FOLDER_END
  93. } ENUM_REASON;
  94. typedef DWORD (WINAPI *PFN_CSCENUMPROC)(LPCTSTR, ENUM_REASON, DWORD, DWORD, DWORD, PWIN32_FIND_DATA, LPARAM);
  95. DWORD _CSCEnumDatabase(LPCTSTR pszFolder, BOOL bRecurse, PFN_CSCENUMPROC pfnCB, LPARAM lpContext);
  96. typedef DWORD (WINAPI *PFN_WIN32ENUMPROC)(LPCTSTR, ENUM_REASON, PWIN32_FIND_DATA, LPARAM);
  97. DWORD _Win32EnumFolder(LPCTSTR pszFolder, BOOL bRecurse, PFN_WIN32ENUMPROC pfnCB, LPARAM lpContext);
  98. //
  99. // Statistical information about a particular network share in the CSC database.
  100. //
  101. typedef struct _CSCSHARESTATS
  102. {
  103. int cTotal;
  104. int cPinned;
  105. int cModified;
  106. int cSparse;
  107. int cDirs;
  108. int cAccessUser;
  109. int cAccessGuest;
  110. int cAccessOther;
  111. bool bOffline;
  112. bool bOpenFiles;
  113. } CSCSHARESTATS, *PCSCSHARESTATS;
  114. typedef struct
  115. {
  116. int cShares;
  117. int cTotal;
  118. int cPinned;
  119. int cModified;
  120. int cSparse;
  121. int cDirs;
  122. int cAccessUser;
  123. int cAccessGuest;
  124. int cAccessOther;
  125. int cSharesOffline;
  126. int cSharesWithOpenFiles;
  127. } CSCCACHESTATS, *PCSCCACHESTATS;
  128. //
  129. // These flags indicate if the enumeration should stop when one or more associated
  130. // value's exceed 1. This is useful when you're interested in 0 vs. !0 as opposed
  131. // to an actual count.
  132. // If multiple flags are set, the statistics enumeration continues until the
  133. // values corresponding to ALL set unity flags are non-zero.
  134. //
  135. enum SHARE_STATS_UNITY_FLAGS { SSUF_NONE = 0x00000000, // This is the default.
  136. SSUF_TOTAL = 0x00000001,
  137. SSUF_PINNED = 0x00000002,
  138. SSUF_MODIFIED = 0x00000004,
  139. SSUF_SPARSE = 0x00000008,
  140. SSUF_DIRS = 0x00000010,
  141. SSUF_ACCUSER = 0x00000020,
  142. SSUF_ACCGUEST = 0x00000040,
  143. SSUF_ACCOTHER = 0x00000080,
  144. SSUF_ACCAND = 0x00000100, // Must match all set access mask flags.
  145. SSUF_ACCOR = 0x00000200, // Match at least one access mask flag.
  146. SSUF_ALL = 0x000000FF };
  147. //
  148. // These flags indicate if any cache items should be excluded from the enumeration.
  149. // By default, the value is 0 (everything included). For perf reasons, we use the
  150. // same flags defined in cscapi.h.
  151. //
  152. enum SHARE_STATS_EXCLUDE_FLAGS {
  153. SSEF_NONE = 0x00000000, // Default. Include everything.
  154. SSEF_LOCAL_MOD_DATA = FLAG_CSC_COPY_STATUS_DATA_LOCALLY_MODIFIED,
  155. SSEF_LOCAL_MOD_ATTRIB = FLAG_CSC_COPY_STATUS_ATTRIB_LOCALLY_MODIFIED,
  156. SSEF_LOCAL_MOD_TIME = FLAG_CSC_COPY_STATUS_TIME_LOCALLY_MODIFIED,
  157. SSEF_LOCAL_DELETED = FLAG_CSC_COPY_STATUS_LOCALLY_DELETED,
  158. SSEF_LOCAL_CREATED = FLAG_CSC_COPY_STATUS_LOCALLY_CREATED,
  159. SSEF_STALE = FLAG_CSC_COPY_STATUS_STALE,
  160. SSEF_SPARSE = FLAG_CSC_COPY_STATUS_SPARSE,
  161. SSEF_ORPHAN = FLAG_CSC_COPY_STATUS_ORPHAN,
  162. SSEF_SUSPECT = FLAG_CSC_COPY_STATUS_SUSPECT,
  163. SSEF_CSCMASK = FLAG_CSC_COPY_STATUS_DATA_LOCALLY_MODIFIED |
  164. FLAG_CSC_COPY_STATUS_ATTRIB_LOCALLY_MODIFIED |
  165. FLAG_CSC_COPY_STATUS_TIME_LOCALLY_MODIFIED |
  166. FLAG_CSC_COPY_STATUS_LOCALLY_DELETED |
  167. FLAG_CSC_COPY_STATUS_LOCALLY_CREATED |
  168. FLAG_CSC_COPY_STATUS_STALE |
  169. FLAG_CSC_COPY_STATUS_SPARSE |
  170. FLAG_CSC_COPY_STATUS_ORPHAN |
  171. FLAG_CSC_COPY_STATUS_SUSPECT,
  172. SSEF_DIRECTORY = 0x01000000,
  173. SSEF_FILE = 0x02000000,
  174. SSEF_NOACCUSER = 0x04000000, // Exclude if no USER access.
  175. SSEF_NOACCGUEST = 0x08000000, // Exclude if no GUEST access.
  176. SSEF_NOACCOTHER = 0x10000000, // Exclude if no OTHER access.
  177. SSEF_NOACCAND = 0x20000000 // Treat previous 3 flags as single mask.
  178. };
  179. typedef struct
  180. {
  181. DWORD dwExcludeFlags; // [in] SSEF_XXXXX flags.
  182. DWORD dwUnityFlags; // [in] SSUF_XXXXX flags.
  183. bool bAccessInfo; // [in] Implied 'T' if unity or exclude access bits are set.
  184. bool bEnumAborted; // [out]
  185. } CSCGETSTATSINFO, *PCSCGETSTATSINFO;
  186. BOOL _GetShareStatistics(LPCTSTR pszShare, PCSCGETSTATSINFO pi, PCSCSHARESTATS pss);
  187. BOOL _GetCacheStatistics(PCSCGETSTATSINFO pi, PCSCCACHESTATS pcs);
  188. BOOL _GetShareStatisticsForUser(LPCTSTR pszShare, PCSCGETSTATSINFO pi, PCSCSHARESTATS pss);
  189. BOOL _GetCacheStatisticsForUser(PCSCGETSTATSINFO pi, PCSCCACHESTATS pcs);
  190. // Higher level wrapper for IDA stuff
  191. class CIDArray
  192. {
  193. private:
  194. STGMEDIUM m_Medium;
  195. LPIDA m_pIDA;
  196. IShellFolder *m_psf;
  197. public:
  198. CIDArray() : m_pIDA(NULL), m_psf(NULL)
  199. {
  200. ZeroMemory(&m_Medium, sizeof(m_Medium));
  201. }
  202. ~CIDArray();
  203. HRESULT Initialize(IDataObject *pdobj);
  204. HRESULT GetFolderPath(LPTSTR pszPath, UINT cch);
  205. HRESULT GetItemPath(UINT iItem, LPTSTR pszPath, UINT cch, DWORD *pdwAttribs);
  206. UINT Count() { return m_pIDA ? m_pIDA->cidl : 0; }
  207. };
  208. //
  209. // Trivial class to ensure cleanup of FindFirst/FindNext handles.
  210. // Perf should be as close as possible to a simple handle so most
  211. // operations are defined inline.
  212. // Implementation is in enum.cpp
  213. //
  214. class CCscFindHandle
  215. {
  216. public:
  217. CCscFindHandle(HANDLE handle = INVALID_HANDLE_VALUE)
  218. : m_handle(handle), m_bOwns(INVALID_HANDLE_VALUE != handle) { }
  219. CCscFindHandle(const CCscFindHandle& rhs)
  220. : m_handle(INVALID_HANDLE_VALUE), m_bOwns(false)
  221. { *this = rhs; }
  222. ~CCscFindHandle(void)
  223. { Close(); }
  224. void Close(void);
  225. HANDLE Detach(void) const
  226. { m_bOwns = false; return m_handle; }
  227. void Attach(HANDLE handle)
  228. { Close(); m_handle = handle; m_bOwns = true; }
  229. operator HANDLE() const
  230. { return m_handle; }
  231. bool IsValid(void) const
  232. { return INVALID_HANDLE_VALUE != m_handle; }
  233. CCscFindHandle& operator = (HANDLE handle)
  234. { Attach(handle); return *this; }
  235. CCscFindHandle& operator = (const CCscFindHandle& rhs);
  236. private:
  237. mutable HANDLE m_handle;
  238. mutable bool m_bOwns;
  239. };
  240. class CMutexAutoRelease
  241. {
  242. public:
  243. explicit CMutexAutoRelease(HANDLE hmutex)
  244. : m_hmutex(hmutex) { }
  245. ~CMutexAutoRelease(void)
  246. {
  247. if (m_hmutex)
  248. {
  249. ReleaseMutex(m_hmutex);
  250. CloseHandle(m_hmutex);
  251. }
  252. }
  253. private:
  254. HANDLE m_hmutex;
  255. CMutexAutoRelease(const CMutexAutoRelease& rhs);
  256. CMutexAutoRelease& operator = (const CMutexAutoRelease& rhs);
  257. };
  258. //
  259. // Ensures CoInitialize/CoUninitialize is exception-safe.
  260. //
  261. class CCoInit
  262. {
  263. public:
  264. CCoInit(void)
  265. : m_hr(CoInitialize(NULL)) { }
  266. ~CCoInit(void)
  267. { if (SUCCEEDED(m_hr)) CoUninitialize(); }
  268. HRESULT Result(void) const
  269. { return m_hr; }
  270. private:
  271. HRESULT m_hr;
  272. };
  273. // String formatting functions - *ppszResult must be LocalFree'd
  274. DWORD FormatStringID(LPTSTR *ppszResult, HINSTANCE hInstance, UINT idStr, ...);
  275. DWORD FormatString(LPTSTR *ppszResult, LPCTSTR pszFormat, ...);
  276. DWORD FormatSystemError(LPTSTR *ppszResult, DWORD dwSysError);
  277. DWORD vFormatStringID(LPTSTR *ppszResult, HINSTANCE hInstance, UINT idStr, va_list *pargs);
  278. DWORD vFormatString(LPTSTR *ppszResult, LPCTSTR pszFormat, va_list *pargs);
  279. void EnableDlgItems(HWND hwndDlg, const UINT* pCtlIds, int cCtls, bool bEnable);
  280. void ShowDlgItems(HWND hwndDlg, const UINT* pCtlIds, int cCtls, bool bShow);
  281. //
  282. // We commonly use groups of CSC status flags together.
  283. // Define them here so we're consistent throughout the project.
  284. //
  285. #define FLAG_CSCUI_COPY_STATUS_LOCALLY_DIRTY (FLAG_CSC_COPY_STATUS_DATA_LOCALLY_MODIFIED | \
  286. FLAG_CSC_COPY_STATUS_LOCALLY_DELETED | \
  287. FLAG_CSC_COPY_STATUS_LOCALLY_CREATED)
  288. #define FLAG_CSCUI_COPY_STATUS_ALL_DIRTY (FLAG_CSC_COPY_STATUS_DATA_LOCALLY_MODIFIED | \
  289. FLAG_CSC_COPY_STATUS_ATTRIB_LOCALLY_MODIFIED | \
  290. FLAG_CSC_COPY_STATUS_TIME_LOCALLY_MODIFIED | \
  291. FLAG_CSC_COPY_STATUS_LOCALLY_DELETED | \
  292. FLAG_CSC_COPY_STATUS_LOCALLY_CREATED)
  293. //
  294. // Some helper inlines for querying cache item access information.
  295. //
  296. inline bool CscCheckAccess(DWORD dwShareStatus, DWORD dwShift, DWORD dwAccessType)
  297. {
  298. return 0 != ((dwShareStatus >> dwShift) & dwAccessType);
  299. }
  300. inline bool CscAccessUserRead(DWORD dwShareStatus)
  301. {
  302. return CscCheckAccess(dwShareStatus, FLAG_CSC_USER_ACCESS_SHIFT_COUNT, FLAG_CSC_READ_ACCESS);
  303. }
  304. inline bool CscAccessUserWrite(DWORD dwShareStatus)
  305. {
  306. return CscCheckAccess(dwShareStatus, FLAG_CSC_USER_ACCESS_SHIFT_COUNT, FLAG_CSC_WRITE_ACCESS);
  307. }
  308. inline bool CscAccessUser(DWORD dwShareStatus)
  309. {
  310. return 0 != (dwShareStatus & FLAG_CSC_USER_ACCESS_MASK);
  311. }
  312. inline bool CscAccessGuestRead(DWORD dwShareStatus)
  313. {
  314. return CscCheckAccess(dwShareStatus, FLAG_CSC_GUEST_ACCESS_SHIFT_COUNT, FLAG_CSC_READ_ACCESS);
  315. }
  316. inline bool CscAccessGuestWrite(DWORD dwShareStatus)
  317. {
  318. return CscCheckAccess(dwShareStatus, FLAG_CSC_GUEST_ACCESS_SHIFT_COUNT, FLAG_CSC_WRITE_ACCESS);
  319. }
  320. inline bool CscAccessGuest(DWORD dwShareStatus)
  321. {
  322. return 0 != (dwShareStatus & FLAG_CSC_GUEST_ACCESS_MASK);
  323. }
  324. inline bool CscAccessOtherRead(DWORD dwShareStatus)
  325. {
  326. return CscCheckAccess(dwShareStatus, FLAG_CSC_OTHER_ACCESS_SHIFT_COUNT, FLAG_CSC_READ_ACCESS);
  327. }
  328. inline bool CscAccessOtherWrite(DWORD dwShareStatus)
  329. {
  330. return CscCheckAccess(dwShareStatus, FLAG_CSC_OTHER_ACCESS_SHIFT_COUNT, FLAG_CSC_WRITE_ACCESS);
  331. }
  332. inline bool CscAccessOther(DWORD dwShareStatus)
  333. {
  334. return 0 != (dwShareStatus & FLAG_CSC_OTHER_ACCESS_MASK);
  335. }
  336. inline bool CscCanUserMergeFile(DWORD dwStatus)
  337. {
  338. return (CscAccessUserWrite(dwStatus) || CscAccessGuestWrite(dwStatus));
  339. }
  340. //
  341. // template inlines avoid the side-effects of min/max macros.
  342. //
  343. template <class T>
  344. inline const T&
  345. MAX(const T& a, const T& b)
  346. {
  347. return a > b ? a : b;
  348. }
  349. template <class T>
  350. inline const T&
  351. MIN(const T& a, const T& b)
  352. {
  353. return a < b ? a : b;
  354. }
  355. class CWin32Handle
  356. {
  357. public:
  358. CWin32Handle(HANDLE handle)
  359. : m_handle(handle) { }
  360. CWin32Handle(void)
  361. : m_handle(NULL) { }
  362. ~CWin32Handle(void)
  363. { Close(); }
  364. void Close(void)
  365. { if (m_handle) CloseHandle(m_handle); m_handle = NULL; }
  366. operator HANDLE() const
  367. { return m_handle; }
  368. HANDLE *HandlePtr(void)
  369. { TraceAssert((NULL == m_handle)); return &m_handle; }
  370. private:
  371. HANDLE m_handle;
  372. //
  373. // Prevent copy.
  374. // This class is only intended for automatic handle cleanup.
  375. //
  376. CWin32Handle(const CWin32Handle& rhs);
  377. CWin32Handle& operator = (const CWin32Handle& rhs);
  378. };
  379. HRESULT DataObject_SetGlobal(IDataObject *pdtobj, CLIPFORMAT cf, HGLOBAL hGlobal);
  380. HRESULT DataObject_SetDWORD(IDataObject *pdtobj, CLIPFORMAT cf, DWORD dw);
  381. HRESULT DataObject_GetDWORD(IDataObject *pdtobj, CLIPFORMAT cf, DWORD *pdwOut);
  382. HRESULT SetPreferredDropEffect(IDataObject *pdtobj, DWORD dwEffect);
  383. DWORD GetPreferredDropEffect(IDataObject *pdtobj);
  384. HRESULT SetLogicalPerformedDropEffect(IDataObject *pdtobj, DWORD dwEffect);
  385. DWORD GetLogicalPerformedDropEffect(IDataObject *pdtobj);
  386. //
  387. // Simple class for automating the display and resetting of a wait cursor.
  388. //
  389. class CAutoWaitCursor
  390. {
  391. public:
  392. CAutoWaitCursor(void)
  393. : m_hCursor(SetCursor(LoadCursor(NULL, IDC_WAIT)))
  394. { ShowCursor(TRUE); }
  395. ~CAutoWaitCursor(void)
  396. { Reset(); }
  397. void Reset(void);
  398. private:
  399. HCURSOR m_hCursor;
  400. };
  401. class CAutoSetRedraw
  402. {
  403. public:
  404. CAutoSetRedraw(HWND hwnd)
  405. : m_hwnd(hwnd) { }
  406. CAutoSetRedraw(HWND hwnd, bool bSet)
  407. : m_hwnd(hwnd) { Set(bSet); }
  408. ~CAutoSetRedraw(void)
  409. { Set(true); }
  410. void Set(bool bSet)
  411. { SendMessage(m_hwnd, WM_SETREDRAW, (WPARAM)bSet, 0); }
  412. private:
  413. HWND m_hwnd;
  414. };
  415. #endif // _UTIL_H_