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.

256 lines
6.3 KiB

  1. /*
  2. * V R E N U M . C P P
  3. *
  4. * Virtual root enumeration
  5. *
  6. * Copyright 1986-1997 Microsoft Corporation, All Rights Reserved
  7. */
  8. #include "_vroot.h"
  9. LPCWSTR __fastcall
  10. PwszStripMetaPrefix (LPCWSTR pwszUrl)
  11. {
  12. // All metabase virtual roots are identified by the
  13. // metabase path, minus a given prefix.
  14. //
  15. // These paths uniformly look like:
  16. //
  17. // '/lm/w3svc/' <site number> '/root'
  18. //
  19. // Since the <site number> is an unnamed integer, the trick to
  20. // skipping this stuff is to search for '/root' in the string
  21. // and then bump ahead 5 characters.
  22. //
  23. Assert (pwszUrl);
  24. if (NULL == (pwszUrl = wcsstr(pwszUrl, L"/root")))
  25. return NULL;
  26. return pwszUrl + 5;
  27. }
  28. // CVRootCache ---------------------------------------------------------------
  29. //
  30. VOID
  31. CChildVRCache::OnNotify (DWORD dwElements, MD_CHANGE_OBJECT_W pcoList[])
  32. {
  33. // Go through the list of changes and see if any scriptmap/vrpath/bindings
  34. // changes have been made to the metabase. If any have changed, then we
  35. // want to invalidate the cache.
  36. //
  37. for (UINT ice = 0; ice < dwElements; ice++)
  38. {
  39. for (UINT ico = 0; ico < pcoList[ice].dwMDNumDataIDs; ico++)
  40. {
  41. // Only invalidate if the stuff that we use to compute our
  42. // values changes changes.
  43. //
  44. if ((pcoList[ice].pdwMDDataIDs[ico] == MD_SERVER_BINDINGS) ||
  45. (pcoList[ice].pdwMDDataIDs[ico] == MD_VR_PATH))
  46. {
  47. DebugTrace ("Dav: CVRoot: invalidating cache\n");
  48. Invalidate();
  49. return;
  50. }
  51. }
  52. }
  53. }
  54. VOID
  55. CChildVRCache::RefreshOp(const IEcb& ecb)
  56. {
  57. // Out with the old...
  58. //
  59. m_cache.Clear();
  60. m_sb.Clear();
  61. // ... and in with the new!
  62. //
  63. (void) ScCacheVroots(ecb);
  64. }
  65. // Cache construction --------------------------------------------------------
  66. //
  67. // class CVirtualRootMetaOp --------------------------------------------------
  68. //
  69. class CVirtualRootMetaOp : public CMetaOp
  70. {
  71. enum { DONT_INHERIT = 0 };
  72. CVRCache& m_cache;
  73. ChainedStringBuffer<WCHAR>& m_sb;
  74. LPCWSTR m_pwszServerDefault;
  75. UINT m_cchServerDefault;
  76. // non-implemented
  77. //
  78. CVirtualRootMetaOp& operator=( const CVirtualRootMetaOp& );
  79. CVirtualRootMetaOp( const CVirtualRootMetaOp& );
  80. // Subclass' operation to perform for each node where
  81. // a value is explicitly set.
  82. //
  83. virtual SCODE __fastcall ScOp(LPCWSTR pwszMbPath, UINT cch);
  84. public:
  85. virtual ~CVirtualRootMetaOp() {}
  86. CVirtualRootMetaOp (const IEcb * pecb,
  87. LPCWSTR pwszPath,
  88. UINT cchServerDefault,
  89. LPCWSTR pwszServerDefault,
  90. ChainedStringBuffer<WCHAR>& sb,
  91. CVRCache& cache)
  92. : CMetaOp (pecb, pwszPath, MD_VR_PATH, STRING_METADATA, FALSE),
  93. m_pwszServerDefault(pwszServerDefault),
  94. m_cchServerDefault(cchServerDefault),
  95. m_cache(cache),
  96. m_sb(sb)
  97. {
  98. }
  99. };
  100. DEC_CONST WCHAR gc_wszLmW3svc[] = L"/lm/w3svc";
  101. DEC_CONST UINT gc_cchLmW3svc = CchConstString(gc_wszLmW3svc);
  102. SCODE __fastcall
  103. CVirtualRootMetaOp::ScOp(LPCWSTR pwszMbPath, UINT cch)
  104. {
  105. CStackBuffer<WCHAR,MAX_PATH> wszBuf;
  106. LPWSTR pwsz;
  107. LPCWSTR pwszUrl;
  108. SCODE sc = S_OK;
  109. auto_ref_ptr<CVRoot> pvr;
  110. auto_ref_ptr<IMDData> pMDData;
  111. Assert (MD_VR_PATH == m_dwId);
  112. Assert (STRING_METADATA == m_dwType);
  113. // If the url ends in a trailing slash, snip it...
  114. //
  115. if (cch && (L'/' == pwszMbPath[cch - 1]))
  116. cch -= 1;
  117. // Construct the full metabase path
  118. //
  119. if (NULL == wszBuf.resize(CbSizeWsz(gc_cchLmW3svc + cch)))
  120. return E_OUTOFMEMORY;
  121. memcpy (wszBuf.get(), gc_wszLmW3svc, gc_cchLmW3svc * sizeof(WCHAR));
  122. memcpy (wszBuf.get() + gc_cchLmW3svc, pwszMbPath, cch * sizeof(WCHAR));
  123. wszBuf[gc_cchLmW3svc + cch] = L'\0';
  124. // Make a copy of the meta path for use as the cache
  125. // key and for use by the CVRoot object.
  126. //
  127. _wcslwr (wszBuf.get());
  128. pwsz = m_sb.Append (CbSizeWsz(gc_cchLmW3svc + cch), wszBuf.get());
  129. // Create a CVRoot object and cache it. First get the metadata
  130. // associated with this path and then construct the CVRoot out
  131. // of that.
  132. //
  133. sc = HrMDGetData (*m_pecb, pwsz, pwsz, pMDData.load());
  134. if (FAILED (sc))
  135. goto ret;
  136. if (NULL != (pwszUrl = PwszStripMetaPrefix (pwsz)))
  137. {
  138. //$ RAID:304272: There is a stress app/case where roots
  139. // are being created that have no vrpath.
  140. //
  141. if (NULL != pMDData->PwszVRPath())
  142. {
  143. // Construct the virtual root object
  144. //
  145. pvr = new CVRoot (pwsz,
  146. static_cast<UINT>(pwszUrl - pwsz),
  147. m_cchServerDefault,
  148. m_pwszServerDefault,
  149. pMDData.get());
  150. DebugTrace ("Dav: CVRoot: caching vroot\n"
  151. " MetaPath: %S\n"
  152. " VrPath: %S\n"
  153. " Bindings: %S\n",
  154. pwsz,
  155. pMDData->PwszVRPath(),
  156. pMDData->PwszBindings());
  157. m_cache.FSet (CRCWsz(pwsz), pvr);
  158. }
  159. //
  160. //$ RAID:304272: end
  161. }
  162. ret:
  163. return sc;
  164. }
  165. SCODE
  166. CChildVRCache::ScCacheVroots (const IEcb& ecb)
  167. {
  168. SCODE sc = S_OK;
  169. CVirtualRootMetaOp vrmo(&ecb,
  170. gc_wszLmW3svc,
  171. m_cchServerDefault,
  172. m_wszServerDefault,
  173. m_sb,
  174. m_cache);
  175. // Gather all the virtual root information
  176. //
  177. sc = vrmo.ScMetaOp();
  178. if (FAILED (sc))
  179. goto ret;
  180. ret:
  181. return sc;
  182. }
  183. // CFindChildren -------------------------------------------------------------
  184. //
  185. BOOL
  186. CChildVRCache::CFindChildren::operator()(
  187. /* [in] */ const CRCWsz& crcwsz,
  188. /* [in] */ const auto_ref_ptr<CVRoot>& arpRoot)
  189. {
  190. // If the root we are checking is a proper ancestor to the
  191. // vroot we are checking, then we will want to push it onto
  192. // the stack.
  193. //
  194. if (!_wcsnicmp (crcwsz.m_pwsz, m_pwsz, m_cch))
  195. {
  196. LPCWSTR pwsz = crcwsz.m_pwsz;
  197. // There are two interesting cases here.
  198. //
  199. // - The child vroot has a physical path that has
  200. // diverged from the parent's.
  201. //
  202. // - The child vroot has a physical path that aligns
  203. // perfectly with the parent.
  204. //
  205. // ie. "/fs" has a VrPath of "f:\fs" and "/fs/bvt" has
  206. // a VrPath of "f:\fs\bvt"
  207. //
  208. // In this latter case, needs to be handled by the
  209. // piece of code that is doing the traversing. In
  210. // most cases, this done by seeing if we traverse
  211. // down into a vroot, etc.
  212. //
  213. Assert (L'\0' == m_pwsz[m_cch]);
  214. if ((L'/' == pwsz[m_cch]) || (L'/' == pwsz[m_cch - 1]))
  215. {
  216. // Push it on the stack
  217. //
  218. m_vrl.push_back (CSortableStrings(m_sb.AppendWithNull(pwsz)));
  219. }
  220. }
  221. return TRUE;
  222. }