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.

408 lines
14 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997 - 1999
  6. //
  7. // File: folder.h
  8. //
  9. //--------------------------------------------------------------------------
  10. #ifndef _INC_CSCUI_FOLDER_H
  11. #define _INC_CSCUI_FOLDER_H
  12. #include <shellp.h> // IShellDetails
  13. #include <shlguidp.h> // IShellFolderViewCb
  14. #include <shlwapip.h> // QITAB, QISearch
  15. #include <shsemip.h> // ILFree(), etc
  16. #include <sfview.h>
  17. #include <comctrlp.h>
  18. #include "util.h"
  19. STDAPI_(void) DllAddRef(void);
  20. STDAPI_(void) DllRelease(void);
  21. #define OLID_SIG 0x4444
  22. #pragma pack(1)
  23. // PIDL format for CSC cache non leaf items...
  24. typedef struct
  25. {
  26. USHORT cb; // Total size of IDList.
  27. USHORT uSig; // IDList signature.
  28. DWORD cbFixed; // Fixed size of IDList.
  29. DWORD dwFileAttributes; // Win32 file attributes.
  30. DWORD dwStatus; // CSC file/folder status flags.
  31. DWORD dwServerStatus; // CSC server status flags.
  32. DWORD dwPinCount; // CSC pin count.
  33. DWORD dwHintFlags; // CSC "hint" flags.
  34. DWORD dwFileSizeHigh; // Win32 file size.
  35. DWORD dwFileSizeLow;
  36. FILETIME ft; // Last write time (from CSC).
  37. DWORD cchNameOfs; // Offset of name part from szPath[0].
  38. TCHAR szPath[0]; // path<nul>name<nul> (variable length).
  39. } OLID;
  40. typedef UNALIGNED OLID *LPOLID;
  41. typedef const UNALIGNED OLID *LPCOLID;
  42. #pragma pack()
  43. class COfflineFilesEnum; // forward
  44. class COfflineFilesViewCallback;
  45. class COfflineDetails;
  46. class COfflineItemsData;
  47. class COfflineItems;
  48. class CFolderCache;
  49. //----------------------------------------------------------------------------
  50. // CFileTypeCache
  51. //----------------------------------------------------------------------------
  52. class CFileTypeCache
  53. {
  54. public:
  55. explicit CFileTypeCache(int cBuckets);
  56. ~CFileTypeCache(void);
  57. HRESULT GetTypeName(
  58. LPCTSTR pszPath,
  59. DWORD dwFileAttributes,
  60. LPTSTR pszDest,
  61. int cchDest);
  62. private:
  63. class CEntry
  64. {
  65. public:
  66. CEntry(LPCTSTR pszExt, LPCTSTR pszTypeName);
  67. ~CEntry(void);
  68. void SetNext(CEntry *pNext)
  69. { m_pNext = pNext; }
  70. CEntry *Next(void) const
  71. { return m_pNext; }
  72. int CompareExt(LPCTSTR pszExt) const
  73. { return lstrcmpi(m_pszExt, pszExt); }
  74. LPCTSTR TypeName(void) const
  75. { return m_pszTypeName; }
  76. bool IsValid(void) const
  77. { return (NULL != m_pszExt) && (NULL != m_pszTypeName); }
  78. private:
  79. LPTSTR m_pszExt;
  80. LPTSTR m_pszTypeName;
  81. CEntry *m_pNext; // Next in hash bucket.
  82. //
  83. // Prevent copy.
  84. //
  85. CEntry(const CEntry& rhs);
  86. CEntry& operator = (const CEntry& rhs);
  87. };
  88. int m_cBuckets;
  89. CEntry **m_prgBuckets;
  90. CRITICAL_SECTION m_cs;
  91. int Hash(LPCTSTR pszExt);
  92. CEntry *Lookup(LPCTSTR pszExt);
  93. HRESULT Add(LPCTSTR pszExt, LPCTSTR pszTypeName);
  94. void Lock(void)
  95. { EnterCriticalSection(&m_cs); }
  96. void Unlock(void)
  97. { LeaveCriticalSection(&m_cs); }
  98. //
  99. // Prevent copy.
  100. //
  101. CFileTypeCache(const CFileTypeCache& rhs);
  102. CFileTypeCache& operator = (const CFileTypeCache& rhs);
  103. };
  104. STDAPI COfflineFilesFolder_CreateInstance(REFIID riid, void **ppv);
  105. class COfflineFilesFolder : public IPersistFolder2,
  106. IShellFolder,
  107. IShellIcon,
  108. IShellIconOverlay
  109. {
  110. public:
  111. static HRESULT WINAPI CreateInstance(REFIID riid, void **ppv);
  112. static INT Open(void);
  113. static HRESULT CreateIDList(LPITEMIDLIST *ppidl);
  114. static HRESULT IdentifyIDList(LPCITEMIDLIST pidl);
  115. static HRESULT CreateLinkOnDesktop(HWND hwndParent);
  116. static HRESULT IsLinkOnDesktop(HWND hwndParent, LPTSTR pszPathOut, UINT cchPathOut);
  117. static HRESULT GetFolder(IShellFolder **ppsf);
  118. // IUnknown
  119. STDMETHOD(QueryInterface)(REFIID riid, void **ppv);
  120. STDMETHOD_(ULONG, AddRef)();
  121. STDMETHOD_(ULONG, Release)();
  122. // IShellFolder
  123. STDMETHOD(ParseDisplayName)(HWND hwnd, LPBC pbc, LPOLESTR pDisplayName,
  124. ULONG *pchEaten, LPITEMIDLIST *ppidl, ULONG *pdwAttributes);
  125. STDMETHOD(EnumObjects)(HWND hwnd, DWORD grfFlags, IEnumIDList **ppEnumIDList);
  126. STDMETHOD(BindToObject)(LPCITEMIDLIST pidl, LPBC pbc, REFIID riid, void **ppvOut);
  127. STDMETHOD(BindToStorage)(LPCITEMIDLIST pidl, LPBC pbc, REFIID riid, void **ppvObj);
  128. STDMETHOD(CompareIDs)(LPARAM lParam, LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2);
  129. STDMETHOD(CreateViewObject)(HWND hwnd, REFIID riid, void **ppvOut);
  130. STDMETHOD(GetAttributesOf)(UINT cidl, LPCITEMIDLIST * apidl, ULONG * rgfInOut);
  131. STDMETHOD(GetUIObjectOf)(HWND hwnd, UINT cidl, LPCITEMIDLIST * apidl, REFIID riid, UINT * prgfInOut, void **ppvOut);
  132. STDMETHOD(GetDisplayNameOf)(LPCITEMIDLIST pidl, DWORD uFlags, STRRET *pName);
  133. STDMETHOD(SetNameOf)(HWND hwnd, LPCITEMIDLIST pidl, LPCOLESTR pszName, DWORD uFlags, LPITEMIDLIST* ppidlOut);
  134. // IPersist
  135. STDMETHOD(GetClassID)(LPCLSID pClassID);
  136. // IPersistFolder
  137. STDMETHOD(Initialize)(LPCITEMIDLIST pidl);
  138. // IPersistFolder2
  139. STDMETHOD(GetCurFolder)(LPITEMIDLIST *pidl);
  140. // IShellIcon
  141. STDMETHOD(GetIconOf)(LPCITEMIDLIST pidl, UINT gil, int *pnIcon);
  142. // IShellIconOverlay
  143. STDMETHOD(GetOverlayIndex)(LPCITEMIDLIST pidl, int * pIndex);
  144. STDMETHOD(GetOverlayIconIndex)(LPCITEMIDLIST pidl, int * pIconIndex);
  145. static bool ValidateIDList(LPCITEMIDLIST pidl);
  146. private:
  147. friend COfflineFilesEnum;
  148. friend COfflineFilesViewCallback;
  149. friend COfflineDetails;
  150. friend COfflineItemsData;
  151. friend COfflineItems;
  152. friend CFolderCache;
  153. friend HRESULT COfflineFilesFolder_CreateInstance(REFIID riid, void **ppv);
  154. COfflineFilesFolder();
  155. ~COfflineFilesFolder();
  156. void _GetSyncStatusString(LPCOLID polid, LPTSTR pszStatus, UINT cchStatus);
  157. void _GetPinStatusString(LPCOLID polid, LPTSTR pszStatus, UINT cchStatus);
  158. void _GetServerStatusString(LPCOLID polid, LPTSTR pszStatus, UINT cchStatus);
  159. void _GetTypeString(LPCOLID polid, LPTSTR pszType, UINT cchType);
  160. void _GetAccessString(LPCOLID polid, LPTSTR pszAccess, UINT cchAccess);
  161. HRESULT GetAssociations(LPCOLID polid, void **ppvQueryAssociations);
  162. BOOL GetClassKey(LPCOLID polid, HKEY *phkeyProgID, HKEY *phkeyBaseID);
  163. static LPCOLID _Validate(LPCITEMIDLIST pidl);
  164. static HRESULT IsOurLink(LPCTSTR pszFile);
  165. static HRESULT _BindToObject(IShellFolder *psf, REFIID riid, LPCITEMIDLIST pidl, void **ppvOut);
  166. static HRESULT ContextMenuCB(IShellFolder *psf, HWND hwndOwner, IDataObject *pdtobj, UINT uMsg, WPARAM wParam, LPARAM lParam);
  167. static LPCTSTR OLID_GetPath(LPCOLID polid, LPTSTR pszPath, UINT cchPath);
  168. static LPCTSTR OLID_GetFullPath(LPCOLID polid, LPTSTR pszPath, UINT cchPath);
  169. static LPCTSTR OLID_GetFileName(LPCOLID polid, LPTSTR pszName, UINT cchName);
  170. static HRESULT OLID_CreateFromUNCPath(LPCTSTR pszPath, const WIN32_FIND_DATA *pfd, DWORD dwStatus, DWORD dwPinCount, DWORD dwHintFlags, DWORD dwServerStatus, LPOLID *ppolid);
  171. static void OLID_GetWin32FindData(LPCOLID polid, WIN32_FIND_DATA *pfd);
  172. static void OLID_CombinePathAndName(LPOLID polid);
  173. static void OLID_SplitPathAndName(LPOLID polid);
  174. static HRESULT OLID_Bind(LPCOLID polid, REFIID riid, void **ppv, LPITEMIDLIST *ppidlFull, LPCITEMIDLIST *ppidlItem);
  175. static HRESULT OLID_CreateSimpleIDList(LPCOLID polid, LPITEMIDLIST *ppidlOut);
  176. LONG _cRef;
  177. LPITEMIDLIST _pidl;
  178. IShellFolderViewCB *_psfvcb;
  179. CFileTypeCache m_FileTypeCache;
  180. };
  181. //
  182. // This class represents a simple cache of CSC status bits for each
  183. // server in the CSC cache. The reason we need this is sort of bogus
  184. // but we have no control over it. When enumerating shares in the CSC
  185. // database, shares on the same server might not return the same online-offline
  186. // status depending on if the share really has a connection or not. The
  187. // problem is that in the network redirector an entire server is either
  188. // online or offline. We display "server" status in the UI so we need to
  189. // merge the status information from each share in the database so that
  190. // we have status information for each server. Clear as mud? This cache
  191. // implements that merging of information so that all a client (i.e. the
  192. // enum code) has to do is call GetServerStatus() with a given UNC path and
  193. // they'll get the status we should be reporting for that path's server.
  194. //
  195. class CServerStatusCache
  196. {
  197. public:
  198. CServerStatusCache(void)
  199. : m_hdpa(NULL) { }
  200. ~CServerStatusCache(void);
  201. //
  202. // This is the only public API for this class. When it's
  203. // called for the first time, the cache is populated. Therefore,
  204. // you can create a cache object but you're not charged much
  205. // until you need to use it.
  206. //
  207. DWORD GetServerStatus(LPCTSTR pszUNC);
  208. private:
  209. //
  210. // A single entry in the cache.
  211. //
  212. class CEntry
  213. {
  214. public:
  215. CEntry(LPCTSTR pszServer, DWORD dwStatus);
  216. ~CEntry(void);
  217. void AddStatus(DWORD dwStatus)
  218. { m_dwStatus |= dwStatus; }
  219. DWORD GetStatus(void) const
  220. { return m_dwStatus; }
  221. LPCTSTR GetServer(void) const
  222. { return m_pszServer; }
  223. bool IsValid(void) const
  224. { return NULL != m_pszServer; }
  225. private:
  226. LPTSTR m_pszServer;
  227. DWORD m_dwStatus;
  228. //
  229. // Prevent copy.
  230. //
  231. CEntry(const CEntry& rhs);
  232. CEntry& operator = (const CEntry& rhs);
  233. };
  234. HDPA m_hdpa; // The DPA for holding entries.
  235. bool AddShareStatus(LPCTSTR pszShare, DWORD dwShareStatus);
  236. CEntry *FindEntry(LPCTSTR pszShare);
  237. LPTSTR ServerFromUNC(LPCTSTR pszShare, LPTSTR pszServer, UINT cchServer);
  238. //
  239. // Prevent copy.
  240. //
  241. CServerStatusCache(const CServerStatusCache& rhs);
  242. CServerStatusCache& operator = (const CServerStatusCache& rhs);
  243. };
  244. class COfflineFilesEnum : public IEnumIDList
  245. {
  246. public:
  247. COfflineFilesEnum(DWORD grfFlags, COfflineFilesFolder *pfolder);
  248. bool IsValid(void) const;
  249. // IUnknown Methods
  250. STDMETHODIMP QueryInterface(REFIID,void **);
  251. STDMETHODIMP_(ULONG) AddRef(void);
  252. STDMETHODIMP_(ULONG) Release(void);
  253. // IEnumIDList Methods
  254. STDMETHODIMP Next(ULONG celt, LPITEMIDLIST *rgelt, ULONG *pceltFetched);
  255. STDMETHODIMP Skip(ULONG celt);
  256. STDMETHODIMP Reset();
  257. STDMETHODIMP Clone(IEnumIDList **ppenum);
  258. protected:
  259. //
  260. // Element of the folder path stack. (_hdsaFolderPaths).
  261. // Includes length to reduce length calculations.
  262. //
  263. struct FolderPathInfo
  264. {
  265. DWORD cchPath; // Chars in path including nul term.
  266. LPTSTR pszPath; // Folder path string.
  267. };
  268. ~COfflineFilesEnum();
  269. LONG _cRef; // ref count
  270. COfflineFilesFolder *_pfolder; // this is what we enumerate
  271. UINT _grfFlags; // enumeration flags
  272. CCscFindHandle _hEnumShares;
  273. CCscFindHandle _hEnum;
  274. HDSA _hdsaFolderPathInfo; // A stack of FolderPathInfo.
  275. LPTSTR _pszPath; // Dynamic scratch buffer for paths.
  276. INT _cchPathBuf; // Current length of _pszPath buffer.
  277. DWORD _dwServerStatus; // dwStatus flags for current server.
  278. CServerStatusCache _ServerStatusCache;
  279. bool _bShowSuperHiddenFiles;
  280. bool _bShowHiddenFiles;
  281. bool _bUserIsAdmin;
  282. private:
  283. bool PopFolderPathInfo(FolderPathInfo *pfpi);
  284. bool PushFolderPathInfo(const FolderPathInfo& fpi)
  285. { return (-1 != DSA_AppendItem(_hdsaFolderPathInfo, (LPVOID)&fpi)); }
  286. bool SaveFolderPath(LPCTSTR pszRoot, LPCTSTR pszFolder);
  287. bool Exclude(const CscFindData& cscfd);
  288. bool OkToEnumFolder(const CscFindData& cscfd);
  289. bool UserHasAccess(const CscFindData& cscfd);
  290. HRESULT GrowPathBuffer(INT cchRequired, INT cchExtra);
  291. };
  292. //----------------------------------------------------------------------------
  293. // Delete handler
  294. //
  295. // This class packages up the operation of deleting a selection of files
  296. // from the folder view. These methods could easily be made members of
  297. // the COfflineFilesFolder class. I think the separation is reasonable.
  298. //----------------------------------------------------------------------------
  299. class CFolderDeleteHandler
  300. {
  301. public:
  302. CFolderDeleteHandler(HWND hwndParent, IDataObject *pdtobj, IShellFolderViewCB *psfvcb);
  303. ~CFolderDeleteHandler(void);
  304. HRESULT DeleteFiles(void);
  305. private:
  306. HWND m_hwndParent;// Parent for any UI.
  307. IDataObject *m_pdtobj; // Data object containing IDArray.
  308. IShellFolderViewCB *m_psfvcb; // View callback for view notifications.
  309. static INT_PTR ConfirmDeleteFilesDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  310. static INT_PTR ConfirmDeleteModifiedFileDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  311. bool ConfirmDeleteFiles(HWND hwndParent);
  312. bool ConfirmDeleteModifiedFile(HWND hwndParent, LPCTSTR pszFile, bool *pbNoToAll, bool *pbCancel);
  313. bool FileModifiedOffline(LPCTSTR pszFile);
  314. bool OthersHaveAccess(LPCTSTR pszFile);
  315. };
  316. HRESULT
  317. CreateOfflineFilesContextMenu(
  318. IDataObject *pdtobj,
  319. REFIID riid,
  320. void **ppv);
  321. #endif // _INC_CSCUI_FOLDER_H