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.

522 lines
20 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997 - 1999
  6. //
  7. // File: filelist.h
  8. //
  9. //--------------------------------------------------------------------------
  10. #ifndef _INC_CSCVIEW_FILELIST_H
  11. #define _INC_CSCVIEW_FILELIST_H
  12. //////////////////////////////////////////////////////////////////////////////
  13. /* File: filelist.h
  14. Description: Simplifies the transmission of a list of share and
  15. associated file names between components of the CSC UI. See
  16. description further below for details.
  17. Classes:
  18. CscFilenameList
  19. CscFilenameList::HSHARE
  20. CscFilenameList::ShareIter
  21. CscFilenameList::FileIter
  22. Note: This module was written to be used by any part of the CSCUI,
  23. not just the viewer. Therefore, I don't assume that the
  24. new operator will throw an exception on allocation failures.
  25. I don't like all the added code to detect allocation failures
  26. but it's not reasonable to expect code in the other components
  27. to become exception-aware with respect to "new" failures.
  28. Revision History:
  29. Date Description Programmer
  30. -------- --------------------------------------------------- ----------
  31. 11/28/97 Initial creation. BrianAu
  32. */
  33. ///////////////////////////////////////////////////////////////////////////////
  34. #ifndef _WINDOWS_
  35. # include <windows.h>
  36. #endif
  37. //
  38. // This set of classes is designed to transfer a list of network share
  39. // names and network file names between components of the CSC UI
  40. // (i.e. wizard, viewer, onestop etc). Data is transferred through
  41. // a formatted byte buffer that is essentially an opaque blob
  42. // to both the sender and receiver. The class CscFilenameList
  43. // was created to prevent the sender and receiver from having
  44. // to understand the buffer format. The buffer is formatted as follows:
  45. //
  46. // +----------------+---------------------------------+
  47. // | <namelist hdr> | <share descriptors> |
  48. // +----------------+---------------------------------+
  49. // | |
  50. // | |
  51. // | <share and file names> |
  52. // | |
  53. // | |
  54. // +--------------------------------------------------+
  55. //
  56. //
  57. // Where: <namelist hdr> is a single block of type CSC_NAMELIST_HDR.
  58. // This block describes the size of the buffer and the
  59. // share count.
  60. //
  61. // <share descriptors> is an array of type CSC_NAMELIST_SHARE_DESC,
  62. // one for each share in the buffer. Each share descriptor
  63. // describes the offset to the share name, the offset
  64. // to the first file name and the number of file names
  65. // in the buffer. All offsets are byte offsets from the
  66. // start of the buffer.
  67. //
  68. // <share and file names> is an array of TCHARs containing the
  69. // names of the shares and files stored in the buffer.
  70. // Each name string is nul-terminated.
  71. //
  72. //
  73. // The following outline describes how I see someone using this feature:
  74. //
  75. // 1. Instantiate a CscFilenameList object (no ctor arguments).
  76. // 2. Call AddShare() whenever a share is to be added.
  77. // 3. Call AddFile() whenever a file is to be added. Note that
  78. // saving the HSHARE returned by AddShare() can make file name addition
  79. // more efficient as it eliminates the need for an internal lookup
  80. // of the associated share name each time a file name is added.
  81. //
  82. // i.e.: CscFilenameList fnl;
  83. // HSHARE hShare = fnl.AddShare("\\\\server\\share");
  84. // fnl.AddFile(hShare, "foo.txt");
  85. // fnl.AddFile(hShare, "bar.txt");
  86. //
  87. // is more efficient than...
  88. //
  89. // CscFilenameList fnl;
  90. // fnl.AddFile("\\\\server\\share", "foo.txt");
  91. // fnl.AddFile("\\\\server\\share", "bar.txt");
  92. //
  93. // ...which is slightly more efficient than...
  94. //
  95. // CscFilenameList fnl;
  96. // fnl.AddFile("\\\\server\\share\\foo.txt");
  97. // fnl.AddFile("\\\\server\\share\\bar.txt");
  98. //
  99. // ...although all 3 methods are supported.
  100. //
  101. // 4. Once all shares and files are added, call CreateListBuffer() to retrieve
  102. // the information formatted in a byte buffer. The buffer is allocated
  103. // on the heap.
  104. // 5. Pass the buffer address to the desired program component.
  105. // 6. The receiving component instantiates a CscFilenameList object passing
  106. // the address of the buffer to the ctor. This initializes the namelist
  107. // so that it merely references the information in the buffer rather than
  108. // duplicating the name information in memory. Note that the buffer must
  109. // remain in memory while this namelist object is in use.
  110. // 7. The receiving component creates a Share Iterator by calling
  111. // CreateShareIterator(). The returned iterator enumerates each of the
  112. // shares contained in the namelist object.
  113. // 8. The receiving component enumerates the shares (receiving an HSHARE) for
  114. // each. To get a share's name string, call GetShareName() passing the
  115. // HSHARE for the desired share.
  116. // 9. For each share, the recieving component creates a File Iterator by
  117. // calling CreateFileIterator() passing the HSHARE for the desired share.
  118. // The returned iterator enumerates each of the file names associated
  119. // with the share.
  120. // 10. Once the operation is complete, FreeListBuffer is called to delete
  121. // the byte buffer created by CreateListBuffer().
  122. //
  123. //
  124. // The following example illustrates this process:
  125. //
  126. //
  127. // void Foo(void)
  128. // {
  129. // CscFilenameList fnl; // Namelist object.
  130. // CscFilenameList::HSHARE hShare; // Share handle.
  131. //
  132. // // Add a share and some files
  133. //
  134. // fnl.AddShare(TEXT("\\\\worf\\ntspecs"), &hShare);
  135. // fnl.AddFile(hShare, TEXT("foo.txt"));
  136. // fnl.AddFile(hShare, TEXT("bar.txt"));
  137. //
  138. // // Add another share and some files.
  139. //
  140. // fnl.AddShare(TEXT("\\\\msoffice\\products"), &hShare);
  141. // fnl.AddFile(hShare, TEXT("word.doc"));
  142. // fnl.AddFile(hShare, TEXT("excel.doc"));
  143. // fnl.AddFile(hShare, TEXT("powerpoint.doc"));
  144. // fnl.AddFile(hShare, TEXT("access.doc"));
  145. //
  146. // // Add another share and more files using the less-efficient
  147. // // method. It's valid, just less efficient.
  148. //
  149. // fnl.AddFile(TEXT("\\\\performance\\poor"), TEXT("turtle.doc"));
  150. // fnl.AddFile(TEXT("\\\\performance\\poor"), TEXT("snail.doc"));
  151. // fnl.AddFile(TEXT("\\\\performance\\poor"), TEXT("inchworm.doc"));
  152. //
  153. // // Create the byte buffer from the namelist and pass it to
  154. // // the receiving component.
  155. //
  156. // LPBYTE pbBuffer = fnl.CreateListBuffer();
  157. // Bar(pbBuffer);
  158. //
  159. // // Delete the byte buffer when we're done.
  160. //
  161. // FreeListBuffer(pbBuffer);
  162. // }
  163. //
  164. //
  165. // void Bar(LPBYTE pbBuffer)
  166. // {
  167. // // Create a new namelist object from the byte buffer.
  168. //
  169. // CscFileNameList fnl(pbBuffer);
  170. //
  171. // // Create a share iterator.
  172. //
  173. // CscFilenameList::ShareIter si = fnl.CreateShareIterator();
  174. // CscFilenameList::HSHARE hShare;
  175. //
  176. // // Iterate over the shares in the namelist collection.
  177. //
  178. // while(si.Next(&hShare))
  179. // {
  180. // _tprintf(TEXT("Share..: \"%s\"\n"), fnl.GetShareName(hShare));
  181. //
  182. // // Create a file iterator for the share.
  183. //
  184. // CscFilenameList::FileIter fi = fl.CreateFileIterator(hShare);
  185. // LPCTSTR pszFile;
  186. //
  187. // // Iterate over the filenames associated with the share.
  188. //
  189. // while(pszFile = fi.Next())
  190. // {
  191. // _tprintf(TEXT("\tFile..: \"%s\"\n"), pszFile);
  192. // }
  193. // }
  194. // }
  195. //
  196. // [brianau - 11/28/97]
  197. //
  198. //
  199. // Namelist byte buffer header block (offset 0).
  200. //
  201. typedef struct
  202. {
  203. DWORD cbSize;
  204. DWORD cShares;
  205. } CSC_NAMELIST_HDR, *PCSC_NAMELIST_HDR;
  206. //
  207. // Namelist byte buffer share descriptor block. Array (one per share)
  208. // starting at offset 12 (immediately following the header block).
  209. //
  210. typedef struct
  211. {
  212. DWORD cbOfsShareName;
  213. DWORD cbOfsFileNames;
  214. DWORD cFiles;
  215. } CSC_NAMELIST_SHARE_DESC, *PCSC_NAMELIST_SHARE_DESC;
  216. class CscFilenameList
  217. {
  218. private:
  219. class Share;
  220. public:
  221. class ShareIter;
  222. class FileIter;
  223. class HSHARE;
  224. // --------------------------------------------------------------------
  225. // CscFilenameList::HSHARE
  226. //
  227. // Share "handle" to communicate the identity of an internal "share"
  228. // object with the client without exposing the share object directly.
  229. // The client just knows an HSHARE. Clients get one as the return
  230. // value from AddShare().
  231. //
  232. class HSHARE
  233. {
  234. public:
  235. HSHARE(void);
  236. HSHARE(const HSHARE& rhs);
  237. HSHARE& operator = (const HSHARE& rhs);
  238. ~HSHARE(void) { }
  239. bool operator ! ()
  240. { return NULL == m_pShare; }
  241. private:
  242. //
  243. // Private so only we can create meaninful HSHARE objects.
  244. //
  245. HSHARE(Share *pShare)
  246. : m_pShare(pShare) { }
  247. Share *m_pShare; // ptr to the actual share object.
  248. friend class CscFilenameList;
  249. friend class ShareIter;
  250. };
  251. // --------------------------------------------------------------------
  252. // CscFilenameList::FileIter
  253. //
  254. // Iterator for enumerating each file name associated with a
  255. // particular share. Clients create one using CreateFileIterator().
  256. //
  257. class FileIter
  258. {
  259. public:
  260. FileIter(void);
  261. ~FileIter(void) { }
  262. FileIter(const FileIter& rhs);
  263. FileIter& operator = (const FileIter& rhs);
  264. LPCTSTR Next(void);
  265. void Reset(void);
  266. private:
  267. FileIter(const Share *pShare);
  268. const Share *m_pShare; // ptr to associated share object.
  269. int m_iFile; // current file iteration index.
  270. friend class CscFilenameList;
  271. };
  272. // --------------------------------------------------------------------
  273. // CscFilenameList::ShareIter
  274. //
  275. // Iterator for enumerating each share in the namelist collection.
  276. // Clients create one using CreateShareIterator().
  277. //
  278. class ShareIter
  279. {
  280. public:
  281. ShareIter(void);
  282. ShareIter(const CscFilenameList& fnl);
  283. ~ShareIter(void) { }
  284. ShareIter(const ShareIter& rhs);
  285. ShareIter& operator = (const ShareIter& rhs);
  286. bool Next(HSHARE *phShare);
  287. void Reset(void);
  288. private:
  289. const CscFilenameList *m_pfnl; // ptr to filename collection obj.
  290. int m_iShare; // current share iteration index.
  291. };
  292. // --------------------------------------------------------------------
  293. // Namelist object public interface.
  294. //
  295. // Create an empty namelist collection ready to accept share and
  296. // file names.
  297. //
  298. CscFilenameList(void);
  299. //
  300. // Create a namelist collection and initialize it with the contents
  301. // of a byte buffer created by CreateListBuffer().
  302. // If bCopy is false, the subsequent namelist object merely references
  303. // the data in the byte buffer rather than duplicating the namestrings
  304. // in memory. If bCopy is true, name strings are created as if the
  305. // names had been added using AddShare() and AddFile(). Note that
  306. // additional share and file name strings may be added at any time.
  307. // However, they are added to internal structures and not to the
  308. // byte buffer. Call CreateListBuffer() to add them to a new byte
  309. // buffer.
  310. //
  311. CscFilenameList(PCSC_NAMELIST_HDR pbNames, bool bCopy);
  312. ~CscFilenameList(void);
  313. //
  314. // Add a share name to the collection. Does not create a
  315. // duplicate share entry if one already exists. Returns a handle
  316. // the a share object.
  317. //
  318. bool AddShare(LPCTSTR pszShare, HSHARE *phShare, bool bCopy = true);
  319. //
  320. // Add a file for a share. More efficient to use the first
  321. // version taking a share handle rather than a share name.
  322. //
  323. bool AddFile(HSHARE& hShare, LPCTSTR pszFile, bool bDirectory = false, bool bCopy = true);
  324. bool AddFile(LPCTSTR pszShare, LPCTSTR pszFile, bool bDirectory = false, bool bCopy = true);
  325. bool AddFile(LPCTSTR pszFullPath, bool bDirectory = false, bool bCopy = true);
  326. bool RemoveFile(HSHARE& hShare, LPCTSTR pszFile);
  327. bool RemoveFile(LPCTSTR pszShare, LPCTSTR pszFile);
  328. bool RemoveFile(LPCTSTR pszFullPath);
  329. //
  330. // Retrieve miscellaneous information about the collection.
  331. //
  332. int GetShareCount(void) const;
  333. int GetFileCount(void) const;
  334. LPCTSTR GetShareName(HSHARE& hShare) const;
  335. int GetShareFileCount(HSHARE& hShare) const;
  336. bool GetShareHandle(LPCTSTR pszShare, HSHARE *phShare) const;
  337. //
  338. // Determine if a given share or file exists in the collection.
  339. // For the FileExists() functions, if bExact is true (the default)
  340. // only exact character-for-character matches return true. If
  341. // bExact is false, the filename "\\server\share\dirA\dirB\foo.txt"
  342. // will match if any of the following four entries exist in the
  343. // namelist:
  344. //
  345. // "\\server\share\dirA\dirB\foo.txt" (exact match)
  346. // "\\server\share\*" (wildcard match)
  347. // "\\server\share\dirA\*" (wildcard match)
  348. // "\\server\share\dirA\dirB\*" (wildcard match)
  349. //
  350. bool ShareExists(LPCTSTR pszShare) const;
  351. bool FileExists(HSHARE& hShare, LPCTSTR pszFile, bool bExact = true) const;
  352. bool FileExists(LPCTSTR pszShare, LPCTSTR pszFile, bool bExact = true) const;
  353. bool FileExists(LPCTSTR pszFullPath, bool bExact = true) const;
  354. //
  355. // Create iterators for enumerating collection contents.
  356. //
  357. ShareIter CreateShareIterator(void) const;
  358. FileIter CreateFileIterator(HSHARE& hShare) const;
  359. //
  360. // Create/free a byte buffer containing the contents of the collection.
  361. //
  362. PCSC_NAMELIST_HDR CreateListBuffer(void) const;
  363. static void FreeListBuffer(PCSC_NAMELIST_HDR pbNames);
  364. //
  365. // Check after initializing object from byte buffer.
  366. //
  367. bool IsValid(void) const
  368. { return m_bValid; }
  369. #ifdef FILELIST_TEST
  370. void Dump(void) const;
  371. void DumpListBuffer(PCSC_NAMELIST_HDR pbBuffer) const;
  372. #endif // FILELIST_TEST
  373. private:
  374. // --------------------------------------------------------------------
  375. // CscFilenameList::NamePtr
  376. //
  377. // Simple wrapper around a string pointer to add a notion of "ownership".
  378. // This lets us store a string address as either a pointer to dynamic
  379. // heap memory (that later must be freed) or the address of a string
  380. // in a character buffer owned by someone else (owner frees it if
  381. // necessary).
  382. //
  383. class NamePtr
  384. {
  385. public:
  386. NamePtr(void)
  387. : m_pszName(NULL),
  388. m_bOwns(false) { }
  389. NamePtr(LPCTSTR pszName, bool bCopy);
  390. ~NamePtr(void);
  391. NamePtr(NamePtr& rhs);
  392. NamePtr& operator = (NamePtr& rhs);
  393. bool IsValid(void) const
  394. { return NULL != m_pszName; }
  395. operator LPCTSTR () const
  396. { return m_pszName; }
  397. private:
  398. LPCTSTR m_pszName; // address of string.
  399. bool m_bOwns; // do we need to free it on destruction?
  400. friend class CscFilenameList;
  401. friend class Share;
  402. };
  403. // --------------------------------------------------------------------
  404. // CscFilenameList::Share
  405. //
  406. // Represents a share in the namelist collection. It's really just
  407. // a convenient container for a share name and a list of file names
  408. // associated with the share.
  409. //
  410. class Share
  411. {
  412. public:
  413. Share(LPCTSTR pszShare, bool bCopy = true);
  414. ~Share(void);
  415. bool AddFile(LPCTSTR pszFile, bool bDirectory = false, bool bCopy = true);
  416. bool RemoveFile(LPCTSTR pszFile);
  417. int FileCount(void) const
  418. { return m_cFiles; }
  419. int ByteCount(void) const
  420. { return (m_cchShareName + m_cchFileNames) * sizeof(TCHAR); }
  421. int Write(LPBYTE pbBufferStart,
  422. CSC_NAMELIST_SHARE_DESC *pDesc,
  423. LPTSTR pszBuffer,
  424. int cchBuffer) const;
  425. #ifdef FILELIST_TEST
  426. void Dump(void) const;
  427. #endif // FILELIST_TEST
  428. private:
  429. int m_cFiles; // Cnt of files in share.
  430. int m_cAllocated; // Cnt of share ptrs allocated.
  431. int m_cchShareName; // Bytes req'd to hold share name.
  432. int m_cchFileNames; // Bytes req'd to hold file names.
  433. NamePtr m_pszShareName; // Address of share name string.
  434. NamePtr *m_rgpszFileNames; // Array of ptrs to file name strings
  435. static int m_cGrow; // File name array growth increment.
  436. int WriteFileNames(LPTSTR pszBuffer, int cchBuffer, DWORD *pcFilesWritten) const;
  437. int WriteName(LPTSTR pszBuffer, int cchBuffer) const;
  438. bool GrowFileNamePtrList(void);
  439. friend class CscFilenameList;
  440. friend class FileIter;
  441. };
  442. // --------------------------------------------------------------------
  443. // Namelist object private members.
  444. //
  445. int m_cShares; // How many shares in collection.
  446. int m_cAllocated; // Allocated size of m_rgpShares[].
  447. Share **m_rgpShares; // Dynamic array of ptrs to Share objects.
  448. bool m_bValid; // Ctor completion check.
  449. static int m_cGrow; // How much to grow array when necessary.
  450. //
  451. // Prevent copy.
  452. //
  453. CscFilenameList(const CscFilenameList& rhs);
  454. CscFilenameList& operator = (const CscFilenameList& rhs);
  455. bool GrowSharePtrList(void);
  456. bool LoadFromBuffer(PCSC_NAMELIST_HDR pbBuffer, bool bCopy);
  457. void ParseFullPath(LPTSTR pszFullPath,
  458. LPTSTR *ppszShare,
  459. LPTSTR *ppszFile) const;
  460. static bool Compare(LPCTSTR pszTemplate, LPCTSTR pszFile, bool *pbExact);
  461. friend class ShareIter;
  462. friend class Share;
  463. };
  464. #endif // _INC_CSCVIEW_FILELIST_H