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.

376 lines
15 KiB

  1. #ifndef __VROOT_H__
  2. #define __VROOT_H__
  3. #include <dbgtrace.h>
  4. #include <iadmw.h>
  5. #include <mddefw.h>
  6. #include <tflist.h>
  7. #include <rwnew.h>
  8. #include <refptr2.h>
  9. #include <listmacr.h>
  10. #define MAX_VROOT_PATH MAX_PATH + 1
  11. class CVRootTable;
  12. #define VROOT_GOOD_SIG 'TOOR'
  13. #define VROOT_BAD_SIG 'ROOT'
  14. //
  15. // There is one of these objects for each of the VRoots defined. It contains
  16. // the VRoot parameters. The only parameter used by the VRoot library is the
  17. // vroot name, but users of this library should inherit from this and make
  18. // their own version which stores all of the other parameters of interest.
  19. //
  20. class CVRoot : public CRefCount2 {
  21. public:
  22. CVRoot() {
  23. m_fInit = FALSE;
  24. m_pPrev = NULL;
  25. m_pNext = NULL;
  26. m_dwSig = VROOT_GOOD_SIG;
  27. }
  28. virtual ~CVRoot();
  29. //
  30. // initialize this class.
  31. //
  32. void Init(LPCSTR pszVRootName, CVRootTable *pVRootTable, LPCWSTR wszConfigPath, BOOL fUpgrade );
  33. //
  34. // get the vroot name (and optionally its length) from this entry.
  35. //
  36. LPCSTR GetVRootName(DWORD *pcch = NULL) {
  37. _ASSERT(m_fInit);
  38. if (pcch != NULL) *pcch = m_cchVRootName;
  39. return m_szVRootName;
  40. }
  41. // get the MB configuration path
  42. LPCWSTR GetConfigPath() { return m_wszConfigPath; }
  43. //
  44. // This needs to be defined by a subclass of CVRoot.
  45. //
  46. virtual HRESULT ReadParameters(IMSAdminBase *pMB,
  47. METADATA_HANDLE hmb) = 0;
  48. //
  49. // Virtual function for handling orphan VRoot during VRootRescan/VRootDelete
  50. //
  51. virtual void DispatchDropVRoot() {};
  52. // the next and previous pointers for our list
  53. CVRoot *m_pPrev;
  54. CVRoot *m_pNext;
  55. #ifdef DEBUG
  56. LIST_ENTRY m_DebugList;
  57. #endif
  58. protected:
  59. DWORD m_dwSig;
  60. BOOL m_fInit;
  61. // the name of this vroot (alt.binaries for example) and its length.
  62. char m_szVRootName[MAX_VROOT_PATH];
  63. DWORD m_cchVRootName;
  64. // the table which owns us
  65. CVRootTable *m_pVRootTable;
  66. // our config path in the metabase
  67. WCHAR m_wszConfigPath[MAX_VROOT_PATH];
  68. // upgrad flag
  69. BOOL m_fUpgrade;
  70. };
  71. typedef CRefPtr2<CVRoot> VROOTPTR;
  72. //
  73. // an implementation of CVRoot which reads the parameters likely to be used
  74. // by all IIS based client of this VRoot implementation.
  75. //
  76. class CIISVRoot : public CVRoot {
  77. public:
  78. virtual ~CIISVRoot() {}
  79. void Init(void *pContext, // ignored
  80. LPCSTR pszVRootName, // passed to CVRoot::Init
  81. CVRootTable *pVRootTable, // passed to CVRoot::Init
  82. LPCWSTR pwszConfigPath,
  83. BOOL fUpgrade ) // available via GetConfigPath()
  84. {
  85. CVRoot::Init(pszVRootName, pVRootTable, pwszConfigPath, fUpgrade);
  86. m_pContext = pContext;
  87. }
  88. // get the context pointer
  89. void *GetContext() { return m_pContext; }
  90. // SSL properties
  91. DWORD GetSSLAccessMask() { return m_dwSSL; }
  92. // access properties
  93. DWORD GetAccessMask() { return m_dwAccess; }
  94. // is the content indexed?
  95. BOOL IsContentIndexed() { return m_fIsIndexed; }
  96. // this method reads the parameters below from the metabase
  97. virtual HRESULT ReadParameters(IMSAdminBase *pMB,
  98. METADATA_HANDLE hmb);
  99. protected:
  100. // this method reads a dword from the metabase (wraps GetData())
  101. virtual HRESULT GetDWord(IMSAdminBase *pMB,
  102. METADATA_HANDLE hmb,
  103. DWORD dwId,
  104. DWORD *pdw);
  105. // this method reads a string from the metabase (wraps GetData())
  106. virtual HRESULT GetString(IMSAdminBase *pMB,
  107. METADATA_HANDLE hmb,
  108. DWORD dwId,
  109. LPWSTR szString,
  110. DWORD *pcString);
  111. protected:
  112. // parameters given to use by the constructor
  113. void *m_pContext;
  114. // parameters read from the metabase
  115. BOOL m_fIsIndexed; // is the content indexed?
  116. BOOL m_fDontLog; // should logging be disabled here?
  117. DWORD m_dwAccess; // access permissions bitmask
  118. DWORD m_dwSSL; // SSL access perm's bitmask
  119. };
  120. //
  121. // a subclass of the above which hides the fact that context is a void *.
  122. //
  123. // template arguments:
  124. // _context_type - the type for the context. must be castable to void *.
  125. //
  126. template <class _context_type>
  127. class CIISVRootTmpl : public CIISVRoot {
  128. public:
  129. virtual ~CIISVRootTmpl() {}
  130. void Init(_context_type pContext,
  131. LPCSTR pszVRootName,
  132. CVRootTable *pVRootTable,
  133. LPCWSTR pwszConfigPath,
  134. BOOL fUpgrade )
  135. {
  136. CIISVRoot::Init((void *) pContext,
  137. pszVRootName,
  138. pVRootTable,
  139. pwszConfigPath,
  140. fUpgrade );
  141. }
  142. // return the context pointer (mostly likely a pointer to an IIS
  143. // instance)
  144. _context_type GetContext() {
  145. return (_context_type) CIISVRoot::GetContext();
  146. }
  147. };
  148. //
  149. // this is a type that points to a function which can create CVRoot objects.
  150. // use it to create your own version of the CVRoot class.
  151. //
  152. // parameters:
  153. // pContext - the context pointer passed into CVRootTable
  154. // pszVRootName - the name of the vroot
  155. // pwszConfigPath - a Unicode string with the path in the metabase for
  156. // this vroot's configuration information.
  157. //
  158. typedef VROOTPTR (*PFNCREATE_VROOT)(void *pContext,
  159. LPCSTR pszVRootName,
  160. CVRootTable *pVRootTable,
  161. LPCWSTR pwszConfigPath,
  162. BOOL fUpgrade );
  163. //
  164. // a function of this type is called when the vroot table is scanned. it
  165. // is passed a copy of the context pointer
  166. //
  167. typedef void (*PFN_VRTABLE_SCAN_NOTIFY)(void *pContext);
  168. typedef void (*PFN_VRENUM_CALLBACK)(void *pEnumContext,
  169. CVRoot *pVRoot);
  170. //
  171. // The CVRootTable object keeps a list of VRoots and can find a vroot for
  172. // a given folder.
  173. //
  174. class CVRootTable {
  175. public:
  176. static HRESULT GlobalInitialize();
  177. static void GlobalShutdown();
  178. CVRootTable(void *pContext,
  179. PFNCREATE_VROOT pfnCreateVRoot,
  180. PFN_VRTABLE_SCAN_NOTIFY pfnScanNotify);
  181. virtual ~CVRootTable();
  182. HRESULT Initialize(LPCSTR pszMBPath, BOOL fUpgrade );
  183. HRESULT Shutdown(void);
  184. HRESULT FindVRoot(LPCSTR pszPath, VROOTPTR *ppVRoot);
  185. HRESULT EnumerateVRoots(void *pEnumContext,
  186. PFN_VRENUM_CALLBACK pfnCallback);
  187. private:
  188. VROOTPTR NewVRoot();
  189. HRESULT ScanVRoots( BOOL fUpgrade );
  190. HRESULT InitializeVRoot(CVRoot *pVRoot);
  191. HRESULT InitializeVRoots();
  192. HRESULT ScanVRootsRecursive(METADATA_HANDLE hmbParent,
  193. LPCWSTR pwszKey,
  194. LPCSTR pszVRootName,
  195. LPCWSTR pwszPath,
  196. BOOL fUpgrade );
  197. void InsertVRoot(VROOTPTR pVRoot);
  198. // find a vroot
  199. HRESULT FindVRootInternal(LPCSTR pszPath, VROOTPTR *ppVRoot);
  200. // convert a config path to a vroot name
  201. void ConfigPathToVRootName(LPCWSTR pwszConfigPath, LPSTR szVRootName);
  202. // used to pass metabase notifications back into this object
  203. static void MBChangeNotify(void *pThis,
  204. DWORD cChangeList,
  205. MD_CHANGE_OBJECT_W pcoChangeList[]);
  206. // parameters changed under a vroot
  207. void VRootChange(LPCWSTR pwszConfigPath, LPCSTR pszVRootName);
  208. // a vroot was deleted
  209. void VRootDelete(LPCWSTR pwszConfigPath, LPCSTR pszVRootName);
  210. // a vroot was added
  211. void VRootAdd(LPCWSTR pwszConfigPath, LPCSTR pszVRootName);
  212. // rescan the whole vroot list
  213. void VRootRescan(void);
  214. #ifdef DEBUG
  215. LIST_ENTRY m_DebugListHead;
  216. CShareLockNH m_DebugListLock;
  217. void DebugPushVRoot( CVRoot *pVRoot ) {
  218. _ASSERT( pVRoot );
  219. m_DebugListLock.ExclusiveLock();
  220. InsertTailList( &m_DebugListHead, &pVRoot->m_DebugList );
  221. m_DebugListLock.ExclusiveUnlock();
  222. }
  223. void DebugExpungeVRoot( CVRoot *pVRoot ) {
  224. m_DebugListLock.ExclusiveLock();
  225. RemoveEntryList( &pVRoot->m_DebugList );
  226. m_DebugListLock.ExclusiveUnlock();
  227. }
  228. #endif
  229. // locking: for walking the list either m_lock.ShareLock must be
  230. // held or m_cs must be held. For editting the list both
  231. // m_lock.ExclusiveLock must be held and m_cs must be held.
  232. // When making large changes (such as rebuilding the entire list)
  233. // m_cs should be held until all of the changes are complete.
  234. // lock for the vroot list
  235. CShareLockNH m_lock;
  236. // critical section used for making global changes on the vroot
  237. // list. this is used to make sure that only one thread can editting
  238. // the list at a time
  239. CRITICAL_SECTION m_cs;
  240. // our context pointer
  241. void *m_pContext;
  242. // the path to our metabase area
  243. WCHAR m_wszRootPath[MAX_VROOT_PATH];
  244. DWORD m_cchRootPath;
  245. // have we been initialized?
  246. BOOL m_fInit;
  247. // are we shutting down?
  248. BOOL m_fShuttingDown;
  249. // function to create a new vroot object
  250. PFNCREATE_VROOT m_pfnCreateVRoot;
  251. // function to call when the vroot table is rescanned
  252. PFN_VRTABLE_SCAN_NOTIFY m_pfnScanNotify;
  253. // the list of vroots
  254. TFList<CVRoot> m_listVRoots;
  255. // this RW lock is used to figure out when all of the VRoot objects
  256. // have shutdown. They hold a ShareLock on it for their lifetime,
  257. // so the CVRootTable can grab an ExclusiveLock to wait for all of
  258. // the VRoot objects to disappear.
  259. CShareLockNH m_lockVRootsExist;
  260. // these guys need access to m_lockVRootsExist
  261. friend void CVRoot::Init(LPCSTR, CVRootTable *, LPCWSTR, BOOL);
  262. friend CVRoot::~CVRoot();
  263. };
  264. //
  265. // this is a templated version of CIISVRootTable. You tell it the version of
  266. // CVRoot that you are using, and the context type that you are using.
  267. //
  268. // template arguments:
  269. // _CVRoot - a subclass of CVRoot that you'll be using
  270. // _context_type - the type that you'll be using for context information.
  271. // this must be castable to void *.
  272. //
  273. template <class _CVRoot, class _context_type>
  274. class CIISVRootTable {
  275. public:
  276. CIISVRootTable(_context_type pContext,
  277. PFN_VRTABLE_SCAN_NOTIFY pfnScanNotify) :
  278. impl((void *) pContext,
  279. CIISVRootTable<_CVRoot, _context_type>::CreateVRoot, pfnScanNotify)
  280. {
  281. }
  282. HRESULT Initialize(LPCSTR pszMBPath, BOOL fUpgrade ) {
  283. return impl.Initialize(pszMBPath, fUpgrade);
  284. }
  285. HRESULT Shutdown(void) {
  286. return impl.Shutdown();
  287. }
  288. HRESULT FindVRoot(LPCSTR pszPath, CRefPtr2<_CVRoot> *ppVRoot) {
  289. return impl.FindVRoot(pszPath, (VROOTPTR *) ppVRoot);
  290. }
  291. HRESULT EnumerateVRoots(void *pEnumContext,
  292. PFN_VRENUM_CALLBACK pfnCallback)
  293. {
  294. return impl.EnumerateVRoots(pEnumContext, pfnCallback);
  295. }
  296. private:
  297. static VROOTPTR CreateVRoot(void *pContext,
  298. LPCSTR pszVRootName,
  299. CVRootTable *pVRootTable,
  300. LPCWSTR pwszConfigPath,
  301. BOOL fUpgrade)
  302. {
  303. // create the vroot object
  304. CRefPtr2<_CVRoot> pVRoot = new _CVRoot;
  305. // initialize it
  306. pVRoot->Init((_context_type) pContext,
  307. pszVRootName,
  308. pVRootTable,
  309. pwszConfigPath,
  310. fUpgrade );
  311. return (_CVRoot *)pVRoot;
  312. }
  313. CVRootTable impl;
  314. };
  315. #endif