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.

282 lines
7.3 KiB

  1. /*
  2. * _ D I R I T E R . H
  3. *
  4. * Headers for directory ineration object
  5. *
  6. * Copyright 1986-1997 Microsoft Corporation, All Rights Reserved
  7. */
  8. #ifndef __DIRITER_H_
  9. #define __DIRITER_H_
  10. #include <buffer.h>
  11. // Path separators -----------------------------------------------------------
  12. //
  13. DEC_CONST WCHAR gc_wszPathSeparator[] = L"\\";
  14. DEC_CONST WCHAR gc_wszUriSeparator[] = L"/";
  15. // Helper functions ----------------------------------------------------------
  16. //
  17. inline BOOL
  18. IsHidden(const WIN32_FIND_DATAW& fd)
  19. {
  20. return !!(fd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN);
  21. }
  22. inline BOOL
  23. IsDirectory(const WIN32_FIND_DATAW& fd)
  24. {
  25. return !!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
  26. }
  27. // CInitedStringBuffer -------------------------------------------------------
  28. //
  29. template<class T>
  30. class CInitedStringBuffer : public StringBuffer<T>
  31. {
  32. // non-implemented operators
  33. //
  34. CInitedStringBuffer (const CInitedStringBuffer& );
  35. CInitedStringBuffer& operator= (const CInitedStringBuffer& );
  36. public:
  37. CInitedStringBuffer (const T* pszInit, const T* pszSep)
  38. {
  39. // Initialize the uri
  40. //
  41. if (pszInit)
  42. {
  43. Append (pszInit);
  44. if (*(PContents() + CchSize() - 1) != *pszSep)
  45. Append (pszSep);
  46. }
  47. else
  48. Append (pszSep);
  49. }
  50. };
  51. // CResPath ------------------------------------------------------------------
  52. //
  53. template<class T>
  54. class CResPath
  55. {
  56. const T* m_sz; // Path separator
  57. StringBuffer<T>& m_sb;
  58. UINT m_ib;
  59. // non-implemented operators
  60. //
  61. CResPath (const CResPath& );
  62. CResPath& operator= (const CResPath& );
  63. public:
  64. CResPath (StringBuffer<T>& sb, const T* pszSep)
  65. : m_sz(pszSep),
  66. m_sb(sb),
  67. m_ib(sb.CbSize())
  68. {
  69. Assert (m_ib >= sizeof(T));
  70. const T* psz = m_sb.PContents() + ((m_ib/sizeof(T)) - 1);
  71. if (*psz == '\0')
  72. {
  73. Assert (!memcmp (m_sz, psz - 1, sizeof(T)));
  74. m_ib -= sizeof(T);
  75. }
  76. else
  77. Assert (!memcmp (m_sz, psz, sizeof(T)));
  78. }
  79. const T* PszPath(void) const { return m_sb.PContents(); }
  80. void Extend (const T* pszSegment, UINT cch, BOOL fDir)
  81. {
  82. // Append the path segment, and in the case of a
  83. // directory append the separator as well.
  84. //
  85. if (fDir)
  86. {
  87. // Copy over the name, then append a slash and the
  88. // null termination
  89. //
  90. m_sb.AppendAt (m_ib, cch * sizeof(T), pszSegment);
  91. m_sb.Append (2 * sizeof(T), m_sz);
  92. }
  93. else
  94. {
  95. // Copy over the name, then append a null.
  96. T ch = 0;
  97. m_sb.AppendAt (m_ib, cch * sizeof(T), pszSegment);
  98. m_sb.Append (sizeof(T), &ch);
  99. }
  100. }
  101. };
  102. // CDirState -----------------------------------------------------------------
  103. //
  104. class CDirState : public CMTRefCounted
  105. {
  106. HANDLE m_hFind;
  107. WIN32_FIND_DATAW& m_fd;
  108. CInitedStringBuffer<WCHAR> m_sbPathDst;
  109. auto_ref_ptr<CVRoot> m_pvrDst;
  110. CResPath<WCHAR> m_rpUriSrc;
  111. CResPath<WCHAR> m_rpPathSrc;
  112. CResPath<WCHAR> m_rpUriDst;
  113. CResPath<WCHAR> m_rpPathDst;
  114. void Extend (WIN32_FIND_DATAW& fd)
  115. {
  116. BOOL fDirectory = IsDirectory (fd);
  117. UINT cch = static_cast<UINT>(wcslen (fd.cFileName));
  118. m_rpPathSrc.Extend (fd.cFileName, cch, fDirectory);
  119. m_rpPathDst.Extend (fd.cFileName, cch, fDirectory);
  120. // We only want to extend the count of chars NOT INCLUDING
  121. // the NULL
  122. //
  123. m_rpUriSrc.Extend (fd.cFileName, cch, fDirectory);
  124. m_rpUriDst.Extend (fd.cFileName, cch, fDirectory);
  125. }
  126. // non-implemented operators
  127. //
  128. CDirState (const CDirState& );
  129. CDirState& operator= (const CDirState& );
  130. public:
  131. CDirState (StringBuffer<WCHAR>& sbUriSrc,
  132. StringBuffer<WCHAR>& sbPathSrc,
  133. StringBuffer<WCHAR>& sbUriDst,
  134. LPCWSTR pwszPathDst,
  135. CVRoot* pvr,
  136. WIN32_FIND_DATAW& fd)
  137. : m_hFind(INVALID_HANDLE_VALUE),
  138. m_fd(fd),
  139. m_sbPathDst(pwszPathDst, gc_wszPathSeparator),
  140. m_pvrDst(pvr),
  141. m_rpUriSrc(sbUriSrc, gc_wszUriSeparator),
  142. m_rpPathSrc(sbPathSrc, gc_wszPathSeparator),
  143. m_rpUriDst(sbUriDst, gc_wszUriSeparator),
  144. m_rpPathDst(m_sbPathDst, gc_wszPathSeparator)
  145. {
  146. // Clear and/or reset the find data
  147. //
  148. memset (&fd, 0, sizeof(WIN32_FIND_DATAW));
  149. }
  150. ~CDirState()
  151. {
  152. if (m_hFind != INVALID_HANDLE_VALUE)
  153. {
  154. FindClose (m_hFind);
  155. }
  156. }
  157. SCODE ScFindNext(void);
  158. LPCWSTR PwszUri(void) const { return m_rpUriSrc.PszPath(); }
  159. LPCWSTR PwszSource(void) const { return m_rpPathSrc.PszPath(); }
  160. LPCWSTR PwszUriDestination(void) const { return m_rpUriDst.PszPath(); }
  161. LPCWSTR PwszDestination(void) const { return m_rpPathDst.PszPath(); }
  162. CVRoot* PvrDestination(void) const { return m_pvrDst.get(); }
  163. };
  164. // CDirectoryStack -----------------------------------------------------------
  165. //
  166. // Use pragmas to disable the specific level 4 warnings
  167. // that appear when we use the STL. One would hope our version of the
  168. // STL compiles clean at level 4, but alas it doesn't....
  169. //
  170. #pragma warning(disable:4663) // C language, template<> syntax
  171. #pragma warning(disable:4244) // return conversion, data loss
  172. // Turn this warning off for good.
  173. //
  174. #pragma warning(disable:4786) // symbol truncated in debug info
  175. // Put STL includes here
  176. //
  177. #include <list>
  178. // Turn warnings back on
  179. //
  180. #pragma warning(default:4663) // C language, template<> syntax
  181. #pragma warning(default:4244) // return conversion, data loss
  182. typedef std::list<const CDirState*, heap_allocator<const CDirState*> > CDirectoryStack;
  183. // Directory iteration class -------------------------------------------------
  184. //
  185. class CDirIter
  186. {
  187. CInitedStringBuffer<WCHAR> m_sbUriSrc;
  188. CInitedStringBuffer<WCHAR> m_sbPathSrc;
  189. CInitedStringBuffer<WCHAR> m_sbUriDst;
  190. auto_ref_ptr<CDirState> m_pds;
  191. BOOL m_fSubDirectoryIteration;
  192. CDirectoryStack m_stack;
  193. WIN32_FIND_DATAW m_fd;
  194. // NOT IMPLEMENTED
  195. //
  196. CDirIter (const CDirIter&);
  197. CDirIter& operator= (const CDirIter&);
  198. public:
  199. CDirIter (LPCWSTR pwszUri,
  200. LPCWSTR pwszSource,
  201. LPCWSTR pwszUriDestination,
  202. LPCWSTR pwszDestination,
  203. CVRoot* pvrDestination,
  204. BOOL fDoSubDirs = FALSE)
  205. : m_sbUriSrc(pwszUri, gc_wszUriSeparator),
  206. m_sbPathSrc(pwszSource, gc_wszPathSeparator),
  207. m_sbUriDst(pwszUriDestination, gc_wszUriSeparator),
  208. m_fSubDirectoryIteration(fDoSubDirs)
  209. {
  210. // Create the initial directory state
  211. //
  212. m_pds = new CDirState (m_sbUriSrc,
  213. m_sbPathSrc,
  214. m_sbUriDst,
  215. pwszDestination,
  216. pvrDestination,
  217. m_fd);
  218. }
  219. // API -------------------------------------------------------------------
  220. //
  221. SCODE __fastcall ScGetNext (
  222. /* [in] */ BOOL fDoSubDirs = TRUE,
  223. /* [in] */ LPCWSTR pwszNewPath = NULL,
  224. /* [in] */ CVRoot* pvrDestination = NULL);
  225. LPCWSTR PwszSource() const { return m_pds->PwszSource(); }
  226. LPCWSTR PwszDestination() const { return m_pds->PwszDestination(); }
  227. LPCWSTR PwszUri() const { return m_pds->PwszUri(); }
  228. LPCWSTR PwszUriDestination() const { return m_pds->PwszUriDestination(); }
  229. CVRoot* PvrDestination() { return m_pds->PvrDestination(); }
  230. WIN32_FIND_DATAW& FindData() { return m_fd; }
  231. BOOL FDirectory() const { return IsDirectory(m_fd); }
  232. BOOL FHidden() const { return IsHidden(m_fd); }
  233. BOOL FSpecial() const
  234. {
  235. return (!wcscmp (L".", m_fd.cFileName) ||
  236. !wcscmp (L"..", m_fd.cFileName));
  237. }
  238. };
  239. #endif // __DIRITER_H_