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.

405 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 HRESULT OLID_GetFullPath(LPCOLID polid, LPTSTR pszPath, UINT cchPath);
  168. static LPCTSTR OLID_GetFileName(LPCOLID polid, LPTSTR pszName, UINT cchName);
  169. static HRESULT OLID_CreateFromUNCPath(LPCTSTR pszPath, const WIN32_FIND_DATA *pfd, DWORD dwStatus, DWORD dwPinCount, DWORD dwHintFlags, DWORD dwServerStatus, LPOLID *ppolid);
  170. static void OLID_GetWin32FindData(LPCOLID polid, WIN32_FIND_DATA *pfd);
  171. static HRESULT OLID_Bind(LPCOLID polid, REFIID riid, void **ppv, LPITEMIDLIST *ppidlFull, LPCITEMIDLIST *ppidlItem);
  172. static HRESULT OLID_CreateSimpleIDList(LPCOLID polid, LPITEMIDLIST *ppidlOut);
  173. LONG _cRef;
  174. LPITEMIDLIST _pidl;
  175. IShellFolderViewCB *_psfvcb;
  176. CFileTypeCache m_FileTypeCache;
  177. };
  178. //
  179. // This class represents a simple cache of CSC status bits for each
  180. // server in the CSC cache. The reason we need this is sort of bogus
  181. // but we have no control over it. When enumerating shares in the CSC
  182. // database, shares on the same server might not return the same online-offline
  183. // status depending on if the share really has a connection or not. The
  184. // problem is that in the network redirector an entire server is either
  185. // online or offline. We display "server" status in the UI so we need to
  186. // merge the status information from each share in the database so that
  187. // we have status information for each server. Clear as mud? This cache
  188. // implements that merging of information so that all a client (i.e. the
  189. // enum code) has to do is call GetServerStatus() with a given UNC path and
  190. // they'll get the status we should be reporting for that path's server.
  191. //
  192. class CServerStatusCache
  193. {
  194. public:
  195. CServerStatusCache(void)
  196. : m_hdpa(NULL) { }
  197. ~CServerStatusCache(void);
  198. //
  199. // This is the only public API for this class. When it's
  200. // called for the first time, the cache is populated. Therefore,
  201. // you can create a cache object but you're not charged much
  202. // until you need to use it.
  203. //
  204. DWORD GetServerStatus(LPCTSTR pszUNC);
  205. private:
  206. //
  207. // A single entry in the cache.
  208. //
  209. class CEntry
  210. {
  211. public:
  212. CEntry(LPCTSTR pszServer, DWORD dwStatus);
  213. ~CEntry(void);
  214. void AddStatus(DWORD dwStatus)
  215. { m_dwStatus |= dwStatus; }
  216. DWORD GetStatus(void) const
  217. { return m_dwStatus; }
  218. LPCTSTR GetServer(void) const
  219. { return m_pszServer; }
  220. bool IsValid(void) const
  221. { return NULL != m_pszServer; }
  222. private:
  223. LPTSTR m_pszServer;
  224. DWORD m_dwStatus;
  225. //
  226. // Prevent copy.
  227. //
  228. CEntry(const CEntry& rhs);
  229. CEntry& operator = (const CEntry& rhs);
  230. };
  231. HDPA m_hdpa; // The DPA for holding entries.
  232. bool AddShareStatus(LPCTSTR pszShare, DWORD dwShareStatus);
  233. CEntry *FindEntry(LPCTSTR pszShare);
  234. LPTSTR ServerFromUNC(LPCTSTR pszShare, LPTSTR pszServer, UINT cchServer);
  235. //
  236. // Prevent copy.
  237. //
  238. CServerStatusCache(const CServerStatusCache& rhs);
  239. CServerStatusCache& operator = (const CServerStatusCache& rhs);
  240. };
  241. class COfflineFilesEnum : public IEnumIDList
  242. {
  243. public:
  244. COfflineFilesEnum(DWORD grfFlags, COfflineFilesFolder *pfolder);
  245. bool IsValid(void) const;
  246. // IUnknown Methods
  247. STDMETHODIMP QueryInterface(REFIID,void **);
  248. STDMETHODIMP_(ULONG) AddRef(void);
  249. STDMETHODIMP_(ULONG) Release(void);
  250. // IEnumIDList Methods
  251. STDMETHODIMP Next(ULONG celt, LPITEMIDLIST *rgelt, ULONG *pceltFetched);
  252. STDMETHODIMP Skip(ULONG celt);
  253. STDMETHODIMP Reset();
  254. STDMETHODIMP Clone(IEnumIDList **ppenum);
  255. protected:
  256. //
  257. // Element of the folder path stack. (_hdsaFolderPaths).
  258. // Includes length to reduce length calculations.
  259. //
  260. struct FolderPathInfo
  261. {
  262. DWORD cchPath; // Chars in path including nul term.
  263. LPTSTR pszPath; // Folder path string.
  264. };
  265. ~COfflineFilesEnum();
  266. LONG _cRef; // ref count
  267. COfflineFilesFolder *_pfolder; // this is what we enumerate
  268. UINT _grfFlags; // enumeration flags
  269. CCscFindHandle _hEnumShares;
  270. CCscFindHandle _hEnum;
  271. HDSA _hdsaFolderPathInfo; // A stack of FolderPathInfo.
  272. LPTSTR _pszPath; // Dynamic scratch buffer for paths.
  273. INT _cchPathBuf; // Current length of _pszPath buffer.
  274. DWORD _dwServerStatus; // dwStatus flags for current server.
  275. CServerStatusCache _ServerStatusCache;
  276. bool _bShowSuperHiddenFiles;
  277. bool _bShowHiddenFiles;
  278. bool _bUserIsAdmin;
  279. private:
  280. bool PopFolderPathInfo(FolderPathInfo *pfpi);
  281. bool PushFolderPathInfo(const FolderPathInfo& fpi)
  282. { return (-1 != DSA_AppendItem(_hdsaFolderPathInfo, (LPVOID)&fpi)); }
  283. bool SaveFolderPath(LPCTSTR pszRoot, LPCTSTR pszFolder);
  284. bool Exclude(const CscFindData& cscfd);
  285. bool OkToEnumFolder(const CscFindData& cscfd);
  286. bool UserHasAccess(const CscFindData& cscfd);
  287. HRESULT GrowPathBuffer(INT cchRequired, INT cchExtra);
  288. };
  289. //----------------------------------------------------------------------------
  290. // Delete handler
  291. //
  292. // This class packages up the operation of deleting a selection of files
  293. // from the folder view. These methods could easily be made members of
  294. // the COfflineFilesFolder class. I think the separation is reasonable.
  295. //----------------------------------------------------------------------------
  296. class CFolderDeleteHandler
  297. {
  298. public:
  299. CFolderDeleteHandler(HWND hwndParent, IDataObject *pdtobj, IShellFolderViewCB *psfvcb);
  300. ~CFolderDeleteHandler(void);
  301. HRESULT DeleteFiles(void);
  302. private:
  303. HWND m_hwndParent;// Parent for any UI.
  304. IDataObject *m_pdtobj; // Data object containing IDArray.
  305. IShellFolderViewCB *m_psfvcb; // View callback for view notifications.
  306. static INT_PTR ConfirmDeleteFilesDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  307. static INT_PTR ConfirmDeleteModifiedFileDlgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  308. bool ConfirmDeleteFiles(HWND hwndParent);
  309. bool ConfirmDeleteModifiedFile(HWND hwndParent, LPCTSTR pszFile, bool *pbNoToAll, bool *pbCancel);
  310. bool FileModifiedOffline(LPCTSTR pszFile);
  311. bool OthersHaveAccess(LPCTSTR pszFile);
  312. };
  313. HRESULT
  314. CreateOfflineFilesContextMenu(
  315. IDataObject *pdtobj,
  316. REFIID riid,
  317. void **ppv);
  318. #endif // _INC_CSCUI_FOLDER_H