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.

325 lines
8.8 KiB

  1. #include <pch.hxx>
  2. #include "davparse.h"
  3. #include "strconst.h"
  4. #include "shlwapi.h"
  5. #define DEFINE_DAVSTRS
  6. #include "davstrs.h"
  7. #undef DEFINE_DAVSTRS
  8. typedef struct tagELEINFO
  9. {
  10. const WCHAR *pwcTagName;
  11. ULONG ulLen;
  12. HMELE eleID;
  13. } ELEINFO, *LPELEINFO;
  14. typedef struct tagNAMESPACEINFO
  15. {
  16. const WCHAR *pszwNamespace;
  17. DWORD dwLen;
  18. DWORD dwNamespaceID;
  19. } NAMESPACEINFO, *LPNAMESPACEINFO;
  20. static const ELEINFO c_rgDavElements[] =
  21. {
  22. #define PROP_DAV(prop, value) \
  23. { c_szwDAV##prop, ulDAV##prop##Len, HMELE_DAV_##prop },
  24. #include "davdef.h"
  25. };
  26. static const ELEINFO c_rgHTTPMailElements[] =
  27. {
  28. #define PROP_HTTP(prop, value) \
  29. { c_szwDAV##prop, ulDAV##prop##Len, HMELE_HTTPMAIL_##prop },
  30. #include "davdef.h"
  31. };
  32. static const ELEINFO c_rgHotMailElements[] =
  33. {
  34. #define PROP_HOTMAIL(prop, value) \
  35. { c_szwDAV##prop, ulDAV##prop##Len, HMELE_HOTMAIL_##prop },
  36. #include "davdef.h"
  37. };
  38. static const ELEINFO c_rgMailElements[] =
  39. {
  40. #define PROP_MAIL(prop, value) \
  41. { c_szwDAV##prop, ulDAV##prop##Len, HMELE_MAIL_##prop },
  42. #include "davdef.h"
  43. };
  44. static const ELEINFO c_rgContactElements[] =
  45. {
  46. #define PROP_CONTACTS(prop, value) \
  47. { c_szwDAV##prop, ulDAV##prop##Len, HMELE_CONTACTS_##prop },
  48. #include "davdef.h"
  49. };
  50. const HMDICTINFO rgHTTPMailDictionary[] =
  51. {
  52. #define PROP_DAV(prop, value) { DAVNAMESPACE_DAV, c_szDAV##prop },
  53. #define PROP_HTTP(prop, value) { DAVNAMESPACE_HTTPMAIL, c_szDAV##prop },
  54. #define PROP_HOTMAIL(prop, value) { DAVNAMESPACE_HOTMAIL, c_szDAV##prop },
  55. #define PROP_MAIL(prop, value) { DAVNAMESPACE_MAIL, c_szDAV##prop },
  56. #define PROP_CONTACTS(prop, value) { DAVNAMESPACE_CONTACTS, c_szDAV##prop },
  57. { DAVNAMESPACE_UNKNOWN, NULL }, // HMELE_UNKNOWN
  58. #include "davdef.h"
  59. };
  60. static NAMESPACEINFO c_rgNamespaceInfo[] =
  61. {
  62. { DAV_STR_LEN(DavNamespace), DAVNAMESPACE_DAV },
  63. { DAV_STR_LEN(HTTPMailNamespace), DAVNAMESPACE_HTTPMAIL },
  64. { DAV_STR_LEN(HotMailNamespace), DAVNAMESPACE_HOTMAIL },
  65. { DAV_STR_LEN(MailNamespace), DAVNAMESPACE_MAIL },
  66. { DAV_STR_LEN(ContactsNamespace), DAVNAMESPACE_CONTACTS }
  67. };
  68. CXMLNamespace::CXMLNamespace(CXMLNamespace *pParent) :
  69. m_cRef(1),
  70. m_pParent(NULL),
  71. m_pwcPrefix(NULL),
  72. m_ulPrefixLen(0),
  73. m_dwNsID(DAVNAMESPACE_UNKNOWN)
  74. {
  75. if (NULL != pParent)
  76. SetParent(pParent);
  77. }
  78. CXMLNamespace::~CXMLNamespace(void)
  79. {
  80. SafeRelease(m_pParent);
  81. SafeMemFree(m_pwcPrefix);
  82. }
  83. ULONG CXMLNamespace::AddRef(void)
  84. {
  85. return (++m_cRef);
  86. }
  87. ULONG CXMLNamespace::Release(void)
  88. {
  89. if (0 == --m_cRef)
  90. {
  91. delete this;
  92. return 0;
  93. }
  94. return m_cRef;
  95. }
  96. HRESULT CXMLNamespace::Init(
  97. const WCHAR *pwcNamespace,
  98. ULONG ulNSLen,
  99. const WCHAR* pwcPrefix,
  100. ULONG ulPrefixLen)
  101. {
  102. HRESULT hr = S_OK;
  103. if (FAILED(hr = SetPrefix(pwcPrefix, ulPrefixLen)))
  104. goto exit;
  105. hr = SetNamespace(pwcNamespace, ulNSLen);
  106. exit:
  107. return hr;
  108. }
  109. HRESULT CXMLNamespace::SetNamespace(const WCHAR *pwcNamespace, ULONG ulLen)
  110. {
  111. DWORD dwIndex;
  112. LPNAMESPACEINFO pnsi = NULL;
  113. // determine if the namespace is known
  114. for (dwIndex = 0; dwIndex < ARRAYSIZE(c_rgNamespaceInfo); ++dwIndex)
  115. {
  116. pnsi = &c_rgNamespaceInfo[dwIndex];
  117. if ((ulLen == c_rgNamespaceInfo[dwIndex].dwLen) && (0 == StrCmpNW(pwcNamespace, c_rgNamespaceInfo[dwIndex].pszwNamespace, ulLen)))
  118. {
  119. m_dwNsID = c_rgNamespaceInfo[dwIndex].dwNamespaceID;
  120. break;
  121. }
  122. }
  123. return S_OK;
  124. }
  125. HRESULT CXMLNamespace::SetPrefix(const WCHAR *pwcPrefix, ULONG ulLen)
  126. {
  127. HRESULT hr = S_OK;
  128. SafeMemFree(m_pwcPrefix);
  129. m_ulPrefixLen = 0;
  130. if (pwcPrefix && ulLen > 0)
  131. {
  132. // duplicate the prefix, and add it to the map
  133. if (!MemAlloc((void **)&m_pwcPrefix, sizeof(WCHAR) * ulLen))
  134. {
  135. hr = E_OUTOFMEMORY;
  136. goto exit;
  137. }
  138. CopyMemory(m_pwcPrefix, pwcPrefix, sizeof(WCHAR) * ulLen);
  139. m_ulPrefixLen = ulLen;
  140. }
  141. exit:
  142. return hr;
  143. }
  144. DWORD CXMLNamespace::_MapPrefix(
  145. const WCHAR *pwcPrefix,
  146. ULONG ulPrefixLen,
  147. BOOL *pbFoundDefaultNamespace)
  148. {
  149. BOOL bFoundDefault = FALSE;
  150. DWORD dwNsID = DAVNAMESPACE_UNKNOWN;
  151. if ((ulPrefixLen > 0) && (ulPrefixLen == m_ulPrefixLen) && (0 == StrCmpNW(pwcPrefix, m_pwcPrefix, ulPrefixLen)))
  152. {
  153. dwNsID = m_dwNsID;
  154. goto exit;
  155. }
  156. // look for a match in the parent.
  157. if (m_pParent)
  158. dwNsID = m_pParent->_MapPrefix(pwcPrefix, ulPrefixLen, &bFoundDefault);
  159. // if we are a default namespace, and either we didn't find a match in the parent, or
  160. // we found a default namespace match in the parent, this becomes the namespace
  161. if ((NULL == m_pwcPrefix) && (DAVNAMESPACE_UNKNOWN == dwNsID || bFoundDefault))
  162. {
  163. dwNsID = m_dwNsID;
  164. bFoundDefault = TRUE; // may not be true if !bFoundInParent
  165. }
  166. exit:
  167. if (NULL != pbFoundDefaultNamespace)
  168. *pbFoundDefaultNamespace = bFoundDefault;
  169. return dwNsID;
  170. }
  171. static BOOL GetNamespace(
  172. const WCHAR *pwcNamespace,
  173. ULONG ulNsLen,
  174. CXMLNamespace *pNamespace,
  175. const ELEINFO **pprgEleInfo,
  176. DWORD *pdwInfoLength)
  177. {
  178. if (NULL == pNamespace || NULL == pprgEleInfo || NULL == pdwInfoLength)
  179. return FALSE;
  180. BOOL bResult = TRUE;
  181. switch (pNamespace->MapPrefix(pwcNamespace, ulNsLen))
  182. {
  183. case DAVNAMESPACE_DAV:
  184. *pprgEleInfo = c_rgDavElements;
  185. *pdwInfoLength = ARRAYSIZE(c_rgDavElements);
  186. break;
  187. case DAVNAMESPACE_HTTPMAIL:
  188. *pprgEleInfo = c_rgHTTPMailElements;
  189. *pdwInfoLength = ARRAYSIZE(c_rgHTTPMailElements);
  190. break;
  191. case DAVNAMESPACE_HOTMAIL:
  192. *pprgEleInfo = c_rgHotMailElements;
  193. *pdwInfoLength = ARRAYSIZE(c_rgHotMailElements);
  194. break;
  195. case DAVNAMESPACE_MAIL :
  196. *pprgEleInfo = c_rgMailElements;
  197. *pdwInfoLength = ARRAYSIZE(c_rgMailElements);
  198. break;
  199. case DAVNAMESPACE_CONTACTS:
  200. *pprgEleInfo = c_rgContactElements;
  201. *pdwInfoLength = ARRAYSIZE(c_rgContactElements);
  202. break;
  203. default:
  204. *pprgEleInfo = NULL;
  205. *pdwInfoLength = 0;
  206. bResult = FALSE;
  207. break;
  208. }
  209. return bResult;
  210. }
  211. HMELE SearchNamespace(const WCHAR *pwcText, ULONG ulLen, const ELEINFO *prgEleInfo, DWORD cInfo)
  212. {
  213. HMELE hmEle = HMELE_UNKNOWN;
  214. ULONG ulLeft = 0;
  215. ULONG ulRight = cInfo - 1;
  216. ULONG ulCur;
  217. int iCompare;
  218. while (ulLeft <= ulRight)
  219. {
  220. ulCur = ulLeft + ((ulRight - ulLeft) / 2);
  221. iCompare = StrCmpNW(pwcText, prgEleInfo[ulCur].pwcTagName, min(ulLen, prgEleInfo[ulCur].ulLen));
  222. if (0 == iCompare)
  223. {
  224. // if the lengths are the same, it's really a match
  225. if (ulLen == prgEleInfo[ulCur].ulLen)
  226. {
  227. hmEle = prgEleInfo[ulCur].eleID;
  228. break;
  229. }
  230. // if the lengths aren't the same, figure out which string is longer
  231. else if (ulLen > prgEleInfo[ulCur].ulLen)
  232. iCompare = 1;
  233. else
  234. iCompare = -1;
  235. }
  236. if (iCompare < 0)
  237. {
  238. if (ulCur > 0)
  239. ulRight = ulCur - 1;
  240. else
  241. break;
  242. }
  243. else
  244. ulLeft = ulCur + 1;
  245. }
  246. return hmEle;
  247. }
  248. HMELE XMLElementToID(
  249. const WCHAR *pwcText,
  250. ULONG ulLen,
  251. ULONG ulNamespaceLen,
  252. CXMLNamespace *pNamespace)
  253. {
  254. HMELE hmEle = HMELE_UNKNOWN;
  255. const ELEINFO *pEleInfo = NULL;
  256. DWORD cInfo = 0;
  257. ULONG ulNameLen = ulLen;
  258. // if the lengths are the same, there is either no namespace
  259. // or no tagname. either way, we aren't going to find a match.
  260. if ((NULL == pwcText) || (NULL == pNamespace))
  261. goto exit;
  262. // if a namespace was specified, subtract it out of the tag name length
  263. if (0 < ulNamespaceLen)
  264. ulNameLen -= (ulNamespaceLen + 1);
  265. // null terminate the namespace string while we figure out if
  266. // the namespace is known
  267. if (GetNamespace(pwcText, ulNamespaceLen, pNamespace, &pEleInfo, &cInfo))
  268. hmEle = SearchNamespace(&pwcText[ulNamespaceLen + 1], ulNameLen, pEleInfo, cInfo);
  269. exit:
  270. return hmEle;
  271. }