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.

424 lines
12 KiB

  1. /*++
  2. Copyright (c) 1998-2001 Microsoft Corporation
  3. Module Name:
  4. cgroupp.h
  5. Abstract:
  6. The private definitions of config group module.
  7. Author:
  8. Paul McDaniel (paulmcd) 11-Jan-1999
  9. Revision History:
  10. --*/
  11. #ifndef _CGROUPP_H_
  12. #define _CGROUPP_H_
  13. #ifdef __cplusplus
  14. extern "C" {
  15. #endif
  16. //
  17. // The tree.
  18. //
  19. // This is used to do all url prefix matching to decide what app pool
  20. // a url lives in, along with other config group information.
  21. //
  22. // it's a sorted tree made up of 2 data structures: HEADER + ENTRY.
  23. //
  24. // a header is an array of ENTRY pointers that represent siblings
  25. // at a level in the tree. This is sorted by ENTRY::TokenHash. the
  26. // pointers are seperately allocated, and not embedded in the HEADER
  27. // memory.
  28. //
  29. // ENTRY represents a node in the tree. there are 2 types of ENTRY's.
  30. // FullUrl ENTRY's and "dummy" entries. Dummy ENTRY's exist simple as
  31. // place holders. they have children that are FullUrl ENTRY's. they
  32. // are auto-deleted when they are no longer needed.
  33. //
  34. // each ENTRY stores in it the part of the url it is responsible for.
  35. // this is pToken. For all non-site entries this is the string without
  36. // the preceding '/' or the trailing '/'. for top level site ENTRY's
  37. // it is everything up the, and not including, the 3rd '/'.
  38. // e.g. "http://www.microsoft.com:80". These top level sites also
  39. // have NULL ENTRY::pParent.
  40. //
  41. // a tree with these url's in it:
  42. //
  43. // http://www.microsoft.com:80/
  44. // http://www.microsoft.com:80/app1
  45. // http://www.microsoft.com:80/app1/app2
  46. // http://www.microsoft.com:80/dir1/dir2/app3
  47. //
  48. // http://www.msnbc.com:80/dir1/dir2/app1
  49. //
  50. // looks like this:
  51. //
  52. // +-------------------------------------------------------------+
  53. // | +---------------------------+ +-----------------------+ |
  54. // | |http://www.microsoft.com:80| |http://www.msnbc.com:80| |
  55. // | +---------------------------+ +-----------------------+ |
  56. // +-------------------------------------------------------------+
  57. // | |
  58. // +-------------------+ +----------+
  59. // | +----+ +----+ | | +----+ |
  60. // | |app1| |dir1| | | |dir1| |
  61. // | +----+ +----+ | | +----+ |
  62. // +-------------------+ +----------+
  63. // | | |
  64. // +--------+ +--------+ +----------+
  65. // | +----+ | | +----+ | | +----+ |
  66. // | |app2| | | |dir2| | | |dir2| |
  67. // | +----+ | | +----+ | | +----+ |
  68. // +--------+ +--------+ +----------+
  69. // | |
  70. // +--------+ +----------+
  71. // | +----+ | | +----+ |
  72. // | |app3| | | |app3| |
  73. // | +----+ | | +----+ |
  74. // +--------+ +----------+
  75. //
  76. // and this:
  77. //
  78. // g_pSites->UsedCount == 2;
  79. // g_pSites->ppEntries[0] == 0x10;
  80. // g_pSites->ppEntries[1] == 0x20;
  81. //
  82. // 0x10->pParent == NULL;
  83. // 0x10->pChildren == 0x100;
  84. // 0x10->TokenHash == 0x4F74;
  85. // 0x10->TokenLength == 0x0036;
  86. // 0x10->FullUrl == 1;
  87. // 0x10->pToken == L"http://www.microsoft.com:80"
  88. //
  89. // 0x100->UsedCount == 2;
  90. // 0x100->ppEntries[0] == 0x110;
  91. // 0x100->ppEntries[1] == 0x300;
  92. //
  93. // 0x110->pParent == 0x10;
  94. // 0x110->pChildren == 0x200;
  95. // 0x110->TokenHash == 0x9214;
  96. // 0x110->TokenLength == 0x0008;
  97. // 0x110->FullUrl == 1;
  98. // 0x110->pToken == L"app1"
  99. //
  100. // 0x200->UsedCount == 1;
  101. // 0x200->ppEntries[0] == 0x210;
  102. //
  103. // 0x210->pParent == 0x110;
  104. // 0x210->pChildren == NULL;
  105. // 0x210->TokenHash == ;
  106. // 0x210->TokenLength == 0x0008;
  107. // 0x210->FullUrl == 1;
  108. // 0x210->pToken == L"app2"
  109. //
  110. // 0x300->pParent == 0x10;
  111. // 0x300->pChildren == 0x400;
  112. // 0x300->TokenHash == 0xAFDE;
  113. // 0x300->TokenLength == 0x0008;
  114. // 0x300->FullUrl == 0;
  115. // 0x300->pToken == L"dir1"
  116. //
  117. // 0x400->UsedCount == 1;
  118. // 0x400->ppEntries[0] == 0x410;
  119. //
  120. // 0x410->pParent == 0x300;
  121. // 0x410->pChildren == 0x500;
  122. // 0x410->TokenHash == ;
  123. // 0x410->TokenLength == 0x0008;
  124. // 0x410->FullUrl == 0;
  125. // 0x410->pToken == L"dir2"
  126. //
  127. // 0x500->UsedCount == 1;
  128. // 0x500->ppEntries[0] == 0x510;
  129. //
  130. // 0x510->pParent == 0x300;
  131. // 0x510->pChildren == NULL;
  132. // 0x510->TokenHash == ;
  133. // 0x510->TokenLength == 0x0008;
  134. // 0x510->FullUrl == 1;
  135. // 0x510->pToken == L"app3"
  136. //
  137. // 0x20->pParent == NULL;
  138. // 0x20->pChildren == 0x600;
  139. // 0x20->TokenHash == 0x9B0D;
  140. // 0x20->TokenLength == 0x002E;
  141. // 0x20->FullUrl == 0;
  142. // 0x20->pToken == L"http://www.msnbc.com:80"
  143. //
  144. // 0x600->pParent == 0x20;
  145. // 0x600->pChildren == 0x700;
  146. // 0x600->TokenHash == 0xAFDE;
  147. // 0x600->TokenLength == 0x0008;
  148. // 0x600->FullUrl == 0;
  149. // 0x600->pToken == L"dir1"
  150. //
  151. // 0x700->UsedCount == 1;
  152. // 0x700->ppEntries[0] == 0x710;
  153. //
  154. // 0x710->pParent == 0x600;
  155. // 0x710->pChildren == 0x800;
  156. // 0x710->TokenHash == ;
  157. // 0x710->TokenLength == 0x0008;
  158. // 0x710->FullUrl == 0;
  159. // 0x710->pToken == L"dir2"
  160. //
  161. // 0x800->UsedCount == 1;
  162. // 0x800->ppEntries[0] == 0x810;
  163. //
  164. // 0x810->pParent == 0x710;
  165. // 0x810->pChildren == NULL;
  166. // 0x810->TokenHash == 0x9214;
  167. // 0x810->TokenLength == 0x0008;
  168. // 0x810->FullUrl == 1;
  169. // 0x810->pToken == L"app1"
  170. //
  171. //
  172. typedef struct _UL_CG_URL_TREE_HEADER UL_CG_URL_TREE_HEADER, * PUL_CG_URL_TREE_HEADER;
  173. typedef struct _UL_CG_URL_TREE_ENTRY UL_CG_URL_TREE_ENTRY, * PUL_CG_URL_TREE_ENTRY;
  174. #define IS_VALID_TREE_ENTRY(pObject) \
  175. (((pObject) != NULL) && ((pObject)->Signature == UL_CG_TREE_ENTRY_POOL_TAG))
  176. typedef struct _UL_CG_URL_TREE_ENTRY
  177. {
  178. //
  179. // PagedPool
  180. //
  181. //
  182. // base properties for dummy nodes
  183. //
  184. ULONG Signature; // UL_CG_TREE_ENTRY_POOL_TAG
  185. PUL_CG_URL_TREE_ENTRY pParent; // points to the parent entry
  186. PUL_CG_URL_TREE_HEADER pChildren; // points to the child header
  187. ULONG TokenHash; // a Hash() of pToken
  188. ULONG TokenLength; // byte count of pToken
  189. ULONG FullUrl:1; // a full_entry ?
  190. ULONG TransientUrl:1; // a transient url?
  191. //
  192. // extended properties for full nodes
  193. //
  194. HTTP_URL_CONTEXT UrlContext; // context for this url
  195. PUL_CONFIG_GROUP_OBJECT pConfigGroup; // the cfg group for the url
  196. LIST_ENTRY ConfigGroupListEntry; // links into pConfigGroup
  197. //
  198. // the token string follows the struct header
  199. //
  200. WCHAR pToken[0];
  201. } UL_CG_URL_TREE_ENTRY, * PUL_CG_URL_TREE_ENTRY;
  202. //
  203. // this allows us to duplicate the hash value of the entry
  204. // inline with the header. this makes the search faster as
  205. // the hash value is in the cache line and no pointer deref
  206. // is necessary.
  207. //
  208. typedef struct _UL_CG_HEADER_ENTRY
  209. {
  210. ULONG TokenHash;
  211. PUL_CG_URL_TREE_ENTRY pEntry;
  212. } UL_CG_HEADER_ENTRY, *PUL_CG_HEADER_ENTRY;
  213. #define IS_VALID_TREE_HEADER(pObject) \
  214. (((pObject) != NULL) && ((pObject)->Signature == UL_CG_TREE_HEADER_POOL_TAG))
  215. typedef struct _UL_CG_URL_TREE_HEADER
  216. {
  217. //
  218. // PagedPool
  219. //
  220. ULONG Signature; // UL_CG_TREE_HEADER_POOL_TAG
  221. ULONG AllocCount; // the count of allocated space
  222. ULONG UsedCount; // how many entries are used
  223. UL_CG_HEADER_ENTRY pEntries[0]; // the entries
  224. } UL_CG_URL_TREE_HEADER, * PUL_CG_URL_TREE_HEADER;
  225. //
  226. // default settings, CODEWORK move these to the registry ?
  227. //
  228. #define UL_CG_DEFAULT_TREE_WIDTH 10 // used to initially allocate sibling
  229. // arrays + the global site array
  230. //
  231. #define HTTP_PREFIX_COLON_INDEX 4 // the colon location for http: (+4)
  232. #define HTTPS_WILD_PREFIX L"https://*:"
  233. #define HTTPS_WILD_PREFIX_LENGTH (sizeof(HTTPS_WILD_PREFIX)-sizeof(WCHAR))
  234. #define HTTP_WILD_PREFIX L"http://*:"
  235. #define HTTP_WILD_PREFIX_LENGTH (sizeof(HTTP_WILD_PREFIX)-sizeof(WCHAR))
  236. #define HTTP_IP_PREFIX L"http://"
  237. #define HTTP_IP_PREFIX_LENGTH (sizeof(HTTP_IP_PREFIX)-sizeof(WCHAR))
  238. #define HTTPS_IP_PREFIX L"https://"
  239. #define HTTPS_IP_PREFIX_LENGTH (sizeof(HTTPS_IP_PREFIX)-sizeof(WCHAR))
  240. //
  241. // work item for deferred site shutdown
  242. // NOTE: Uses ExQueueWorkItem, not UlQueueWorkItem
  243. //
  244. typedef struct _UL_DEFERRED_REMOVE_ITEM {
  245. UL_WORK_ITEM WorkItem;
  246. ULONG NameLength;
  247. WCHAR pName[0];
  248. } UL_DEFERRED_REMOVE_ITEM, *PUL_DEFERRED_REMOVE_ITEM;
  249. //
  250. // Internal helper functions used in the module
  251. //
  252. //
  253. // misc helpers
  254. //
  255. NTSTATUS
  256. UlpCreateConfigGroupObject(
  257. OUT PUL_CONFIG_GROUP_OBJECT * ppObject
  258. );
  259. NTSTATUS
  260. UlpCleanAllUrls(
  261. IN PUL_CONFIG_GROUP_OBJECT pObject
  262. );
  263. VOID
  264. UlpDeferredRemoveSite(
  265. IN PUL_CG_URL_TREE_ENTRY pEntry
  266. );
  267. VOID
  268. UlpDeferredRemoveSiteWorker(
  269. IN PUL_WORK_ITEM pWorkItem
  270. );
  271. NTSTATUS
  272. UlpSanitizeUrl(
  273. IN PUNICODE_STRING pUrl,
  274. OUT PWSTR * ppUrl
  275. );
  276. //
  277. // tree helpers
  278. //
  279. NTSTATUS
  280. UlpTreeFindNodeWalker(
  281. IN PUL_CG_URL_TREE_ENTRY pEntry,
  282. IN PWSTR pNextToken,
  283. IN OUT PUL_URL_CONFIG_GROUP_INFO pInfo OPTIONAL,
  284. OUT PUL_CG_URL_TREE_ENTRY * ppEntry OPTIONAL
  285. );
  286. NTSTATUS
  287. UlpTreeFindNode(
  288. IN PWSTR pUrl,
  289. IN BOOLEAN CheckWildcard,
  290. IN PUL_HTTP_CONNECTION pHttpConn OPTIONAL,
  291. OUT PUL_URL_CONFIG_GROUP_INFO pInfo OPTIONAL,
  292. OUT PUL_CG_URL_TREE_ENTRY * ppEntry OPTIONAL
  293. );
  294. NTSTATUS
  295. UlpTreeFindIpMatch(
  296. IN PWSTR pUrl,
  297. IN PUL_HTTP_CONNECTION pHttpConn,
  298. OUT PWSTR * ppNextToken,
  299. OUT PUL_CG_URL_TREE_ENTRY * ppEntry
  300. );
  301. NTSTATUS
  302. UlpTreeFindWildcardMatch(
  303. IN PWSTR pUrl,
  304. OUT PWSTR * ppNextToken,
  305. OUT PUL_CG_URL_TREE_ENTRY * ppEntry
  306. );
  307. NTSTATUS
  308. UlpTreeFindSite(
  309. IN PWSTR pUrl,
  310. OUT PWSTR * ppNextToken,
  311. OUT PUL_CG_URL_TREE_ENTRY * ppEntry,
  312. IN BOOLEAN AutoCreate
  313. );
  314. NTSTATUS
  315. UlpTreeFindEntry(
  316. IN PUL_CG_URL_TREE_HEADER pHeader OPTIONAL,
  317. IN PWSTR pToken,
  318. IN ULONG TokenLength,
  319. IN ULONG TokenHash OPTIONAL,
  320. OUT ULONG * pIndex,
  321. OUT ULONG * pTokenHash OPTIONAL
  322. );
  323. NTSTATUS
  324. UlpTreeBinaryFindEntry(
  325. IN PUL_CG_URL_TREE_HEADER pHeader OPTIONAL,
  326. IN PWSTR pToken,
  327. IN ULONG TokenLength,
  328. IN ULONG TokenHash OPTIONAL,
  329. OUT PULONG pIndex
  330. );
  331. NTSTATUS
  332. UlpTreeFreeNode(
  333. IN PUL_CG_URL_TREE_ENTRY pEntry
  334. );
  335. NTSTATUS
  336. UlpTreeInsert(
  337. IN PWSTR pUrl,
  338. OUT PUL_CG_URL_TREE_ENTRY * ppEntry
  339. );
  340. NTSTATUS
  341. UlpTreeInsertEntry(
  342. IN OUT PUL_CG_URL_TREE_HEADER * ppHeader,
  343. IN PUL_CG_URL_TREE_ENTRY pParent OPTIONAL,
  344. IN PWSTR pToken,
  345. IN ULONG TokenLength,
  346. IN ULONG TokenHash,
  347. IN ULONG Index
  348. );
  349. #ifdef __cplusplus
  350. }; // extern "C"
  351. #endif
  352. #endif // _CGROUPP_H_