Leaked source code of windows server 2003
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.

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