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.

308 lines
6.4 KiB

  1. /*
  2. * X F I N D . C P P
  3. *
  4. * XML push model parsing for PROPFIND requests
  5. *
  6. * Copyright 1986-1997 Microsoft Corporation, All Rights Reserved
  7. */
  8. #include "_xml.h"
  9. // class CNFFind -------------------------------------------------------------
  10. //
  11. SCODE
  12. CNFFind::ScCompleteAttribute (void)
  13. {
  14. if (m_state == ST_ENUMLIMIT)
  15. m_state = ST_INENUMREPORT;
  16. return S_OK;
  17. }
  18. SCODE
  19. CNFFind::ScCompleteChildren (
  20. /* [in] */ BOOL fEmptyNode,
  21. /* [in] */ DWORD dwType,
  22. /* [in] */ const WCHAR __RPC_FAR *pwcText,
  23. /* [in] */ ULONG ulLen)
  24. {
  25. switch (m_state)
  26. {
  27. case ST_PROPFIND:
  28. m_state = ST_NODOC;
  29. break;
  30. case ST_PROPS:
  31. case ST_ALLPROP:
  32. case ST_ALLNAMES:
  33. case ST_ENUMREPORT:
  34. m_state = ST_PROPFIND;
  35. break;
  36. case ST_INPROP:
  37. m_state = ST_PROPS;
  38. break;
  39. case ST_INENUMREPORT:
  40. m_state = ST_ENUMREPORT;
  41. break;
  42. case ST_ALLPROPFULL:
  43. m_state = ST_ALLPROP;
  44. break;
  45. case ST_ALLNAMESFULL:
  46. m_state = ST_ALLNAMES;
  47. break;
  48. case ST_ALLPROP_EXCLUDE:
  49. m_state = ST_ALLPROPFULL;
  50. break;
  51. case ST_ALLPROP_EXCLUDE_INPROP:
  52. m_state = ST_ALLPROP_EXCLUDE;
  53. break;
  54. case ST_ALLPROP_INCLUDE:
  55. m_state = ST_ALLPROPFULL;
  56. break;
  57. case ST_ALLPROP_INCLUDE_INPROP:
  58. m_state = ST_ALLPROP_INCLUDE;
  59. break;
  60. }
  61. return S_OK;
  62. }
  63. SCODE
  64. CNFFind::ScHandleNode (
  65. /* [in] */ DWORD dwType,
  66. /* [in] */ DWORD dwSubType,
  67. /* [in] */ BOOL fTerminal,
  68. /* [in] */ const WCHAR __RPC_FAR *pwcText,
  69. /* [in] */ ULONG ulLen,
  70. /* [in] */ ULONG ulNamespaceLen,
  71. /* [in] */ const WCHAR __RPC_FAR *pwcNamespace,
  72. /* [in] */ const ULONG ulNsPrefixLen)
  73. {
  74. LPCWSTR pwszTag;
  75. CStackBuffer<WCHAR> wsz;
  76. SCODE sc = S_FALSE;
  77. UINT cch;
  78. // In the case of a PROPFIND, all the nodes that we are
  79. // interested are XML_ELEMENT nodes. Anything else can
  80. // (and should) be safely ignored.
  81. //
  82. // Returning S_FALSE signifies that we are not handling
  83. // the node (and therefore its children).
  84. //
  85. if (dwType == XML_ELEMENT)
  86. {
  87. cch = ulNamespaceLen + ulLen;
  88. pwszTag = wsz.resize(CbSizeWsz(cch));
  89. if (NULL == pwszTag)
  90. {
  91. sc = E_OUTOFMEMORY;
  92. goto ret;
  93. }
  94. wcsncpy (wsz.get(), pwcNamespace, ulNamespaceLen);
  95. wcsncpy (wsz.get() + ulNamespaceLen, pwcText, ulLen);
  96. *(wsz.get() + cch) = 0;
  97. switch (m_state)
  98. {
  99. case ST_NODOC:
  100. // If this is the topmost node in a propfind request,
  101. // transition to the next state. Since there is no
  102. // parent node to provide scoping, FIsTag() cannot be
  103. // used here!
  104. //
  105. if (!wcscmp (pwszTag, gc_wszPropfind))
  106. {
  107. m_state = ST_PROPFIND;
  108. sc = S_OK;
  109. }
  110. break;
  111. case ST_PROPFIND:
  112. // Look for our well know node types
  113. //
  114. if (FIsTag (pwszTag, gc_wszAllprop))
  115. {
  116. // Tell the context we are interested in all
  117. // properties of the given resources
  118. //
  119. sc = m_cfc.ScGetAllProps (NULL);
  120. if (FAILED (sc))
  121. goto ret;
  122. m_state = ST_ALLPROP;
  123. }
  124. else if (FIsTag (pwszTag, gc_wszPropname))
  125. {
  126. // Tell the context we are interested in all
  127. // property names available in the given resources
  128. //
  129. sc = m_cfc.ScGetAllNames (NULL);
  130. if (FAILED (sc))
  131. goto ret;
  132. m_state = ST_ALLNAMES;
  133. }
  134. else if (FIsTag (pwszTag, gc_wszProp))
  135. {
  136. m_state = ST_PROPS;
  137. sc = S_OK;
  138. }
  139. else if (FIsTag (pwszTag, gc_wszEnumReport))
  140. {
  141. sc = m_cfc.ScEnumReport ();
  142. if (FAILED(sc))
  143. goto ret;
  144. m_state = ST_ENUMREPORT;
  145. }
  146. break;
  147. case ST_PROPS:
  148. // Add the specific property to the set of properties
  149. // we are interested in.
  150. //
  151. sc = m_cfc.ScAddProp (NULL, pwszTag, CFindContext::FIND_PROPLIST_INCLUDE);
  152. if (FAILED (sc))
  153. goto ret;
  154. m_state = ST_INPROP;
  155. break;
  156. case ST_ENUMREPORT:
  157. // Add the report to the report list
  158. //
  159. sc = m_cfc.ScSetReportName (cch, pwszTag);
  160. if (FAILED(sc))
  161. goto ret;
  162. if (S_OK == sc)
  163. m_state = ST_INENUMREPORT;
  164. break;
  165. case ST_ALLPROP:
  166. case ST_ALLNAMES:
  167. // Look for full fidelity node
  168. //
  169. if (FIsTag (pwszTag, gc_wszFullFidelity))
  170. {
  171. // Tell the context we are interested in all
  172. // properties with full fidelity of the given
  173. // resources
  174. //
  175. sc = m_cfc.ScGetFullFidelityProps ();
  176. if (FAILED (sc))
  177. goto ret;
  178. if (ST_ALLPROP == m_state)
  179. {
  180. m_state = ST_ALLPROPFULL;
  181. }
  182. else
  183. {
  184. m_state = ST_ALLNAMESFULL;
  185. }
  186. }
  187. case ST_ALLPROPFULL:
  188. // for the all-props full-fidelity case, there could be
  189. // two lists of props: one exclude list and one include
  190. // list. Exclude list specifies the props the client is
  191. // not interested in and hence need to be removed from
  192. // the response. Similarly include list specifies the
  193. // extra properties the client is interested in.
  194. //
  195. if (FIsTag (pwszTag, gc_wszFullFidelityExclude))
  196. {
  197. m_state = ST_ALLPROP_EXCLUDE;
  198. sc = S_OK;
  199. }
  200. else if (FIsTag (pwszTag, gc_wszFullFidelityInclude))
  201. {
  202. m_state = ST_ALLPROP_INCLUDE;
  203. sc = S_OK;
  204. }
  205. break;
  206. case ST_ALLPROP_EXCLUDE:
  207. sc = m_cfc.ScAddProp (NULL,
  208. pwszTag,
  209. CFindContext::FIND_PROPLIST_EXCLUDE);
  210. if (FAILED (sc))
  211. goto ret;
  212. m_state = ST_ALLPROP_EXCLUDE_INPROP;
  213. break;
  214. case ST_ALLPROP_INCLUDE:
  215. sc = m_cfc.ScAddProp (NULL,
  216. pwszTag,
  217. CFindContext::FIND_PROPLIST_INCLUDE);
  218. if (FAILED (sc))
  219. goto ret;
  220. m_state = ST_ALLPROP_INCLUDE_INPROP;
  221. break;
  222. }
  223. }
  224. else if (dwType == XML_ATTRIBUTE)
  225. {
  226. if ((m_state == ST_INENUMREPORT) && (XML_NS != dwSubType))
  227. {
  228. cch = ulNamespaceLen + ulLen;
  229. pwszTag = wsz.resize(CbSizeWsz(cch));
  230. if (NULL == pwszTag)
  231. {
  232. sc = E_OUTOFMEMORY;
  233. goto ret;
  234. }
  235. wcsncpy (wsz.get(), pwcNamespace, ulNamespaceLen);
  236. wcsncpy (wsz.get() + ulNamespaceLen, pwcText, ulLen);
  237. *(wsz.get() + cch) = 0;
  238. // If this is a limit attribute, make the
  239. // appropriate transition
  240. //
  241. if (!_wcsnicmp (pwszTag, gc_wszLimit, cch))
  242. {
  243. m_state = ST_ENUMLIMIT;
  244. sc = S_OK;
  245. }
  246. }
  247. }
  248. else if (dwType == XML_PCDATA)
  249. {
  250. if (m_state == ST_ENUMLIMIT)
  251. sc = m_cfc.ScSetReportLimit (ulLen, pwcText);
  252. }
  253. ret:
  254. return sc;
  255. }