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.

315 lines
8.0 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1996.
  5. //
  6. // File: HTTPNEG.CXX
  7. //
  8. // Contents: Code to handle multiplexing multiple concurrent
  9. // IHttpNegotiate interfaces.
  10. //
  11. // Classes: CHttpNegHolder
  12. //
  13. // Functions:
  14. //
  15. // History: 01-30-96 JoeS (Joe Souza) Created
  16. //
  17. //----------------------------------------------------------------------------
  18. #include <urlint.h>
  19. #include <urlmon.hxx>
  20. #include "httpneg.hxx"
  21. CHttpNegHolder::CHttpNegHolder(void) : _CRefs()
  22. {
  23. _pCHttpNegNode = NULL;
  24. _cElements = 0;
  25. }
  26. STDMETHODIMP CHttpNegHolder::QueryInterface(REFIID riid, void **ppvObj)
  27. {
  28. VDATEPTROUT(ppvObj, void *);
  29. VDATETHIS(this);
  30. HRESULT hr = NOERROR;
  31. UrlMkDebugOut((DEB_BINDING, "%p _IN CHttpNegHolder::QueryInterface\n", this));
  32. *ppvObj = NULL;
  33. if (riid == IID_IHttpNegotiate)
  34. {
  35. *ppvObj = this;
  36. AddRef();
  37. }
  38. else
  39. {
  40. hr = E_NOINTERFACE;
  41. CHttpNegNode *pNode;
  42. pNode = _pCHttpNegNode;
  43. while (pNode)
  44. {
  45. hr = pNode->GetHttpNegotiate()->QueryInterface(riid, ppvObj);
  46. if (hr == NOERROR)
  47. {
  48. pNode = NULL;
  49. }
  50. else
  51. {
  52. pNode = pNode->GetNextNode();
  53. }
  54. }
  55. }
  56. UrlMkDebugOut((DEB_BINDING, "%p OUT CHttpNegHolder::QueryInterface (hr:%lx\n", this,hr));
  57. return hr;
  58. }
  59. STDMETHODIMP_(ULONG) CHttpNegHolder::AddRef(void)
  60. {
  61. UrlMkDebugOut((DEB_BINDING, "%p _IN CHttpNegHolder::AddRef\n", this));
  62. LONG lRet = ++_CRefs;
  63. UrlMkDebugOut((DEB_BINDING, "%p OUT CHttpNegHolder::AddRef (cRefs:%ld)\n", this,lRet));
  64. return lRet;
  65. }
  66. STDMETHODIMP_(ULONG) CHttpNegHolder::Release(void)
  67. {
  68. UrlMkDebugOut((DEB_BINDING, "%p _IN CHttpNegHolder::Release\n", this));
  69. UrlMkAssert((_CRefs > 0));
  70. LONG lRet = --_CRefs;
  71. if (_CRefs == 0)
  72. {
  73. RemoveAllNodes();
  74. delete this;
  75. }
  76. UrlMkDebugOut((DEB_BINDING, "%p OUT CHttpNegHolder::Release (cRefs:%ld)\n",this,lRet));
  77. return lRet;
  78. }
  79. HRESULT CHttpNegHolder::BeginningTransaction(LPCWSTR szURL, LPCWSTR szHeaders,
  80. DWORD dwReserved, LPWSTR *pszAdditionalHeaders)
  81. {
  82. UrlMkDebugOut((DEB_BINDING, "%p _IN CHttpNegHolder::BeginningTransaction (szURL:%ws, szHeaders:%ws)\n", this, szURL, szHeaders));
  83. VDATETHIS(this);
  84. HRESULT hr = NOERROR;
  85. CHttpNegNode *pNode;
  86. LPWSTR szTmp = NULL, szNew = NULL, szRunning = NULL;
  87. pNode = _pCHttpNegNode;
  88. while (pNode)
  89. {
  90. hr = pNode->GetHttpNegotiate()->BeginningTransaction(szURL, szHeaders, dwReserved, &szNew);
  91. UrlMkDebugOut((DEB_BINDING, "%p === CHttpNegHolder::BeginningTransaction (szNew:%ws )\n", this, szNew));
  92. if (hr == NOERROR && szNew != NULL && szRunning != NULL)
  93. {
  94. szTmp = szRunning;
  95. szRunning = new WCHAR [wcslen(szTmp) + 1 + wcslen(szNew) + 1];
  96. if (szRunning)
  97. {
  98. if (szTmp)
  99. {
  100. wcscpy(szRunning, szTmp);
  101. wcscat(szRunning, szNew);
  102. }
  103. else
  104. {
  105. wcscpy(szRunning, szNew);
  106. }
  107. }
  108. else
  109. {
  110. hr = E_OUTOFMEMORY;
  111. }
  112. delete szTmp;
  113. delete szNew;
  114. if (hr != NOERROR)
  115. {
  116. goto BegTransExit;
  117. }
  118. }
  119. else
  120. {
  121. szRunning = szNew;
  122. }
  123. pNode = pNode->GetNextNode();
  124. }
  125. *pszAdditionalHeaders = szRunning;
  126. BegTransExit:
  127. UrlMkDebugOut((DEB_BINDING, "%p OUT CHttpNegHolder::BeginningTransaction (pszAdditionalHeaders:%ws )\n", this, *pszAdditionalHeaders));
  128. return hr;
  129. }
  130. HRESULT CHttpNegHolder::OnResponse(DWORD dwResponseCode,LPCWSTR szResponseHeaders,
  131. LPCWSTR szRequestHeaders,LPWSTR *pszAdditionalRequestHeaders)
  132. {
  133. UrlMkDebugOut((DEB_BINDING, "%p _IN CHttpNegHolder::OnError\n", this));
  134. VDATETHIS(this);
  135. HRESULT hr = NOERROR;
  136. CHttpNegNode *pNode;
  137. LPWSTR szTmp = NULL, szNew = NULL, szRunning = NULL;
  138. pNode = _pCHttpNegNode;
  139. while (pNode)
  140. {
  141. hr = pNode->GetHttpNegotiate()->OnResponse(dwResponseCode, szResponseHeaders, szRequestHeaders, &szNew);
  142. if (hr == NOERROR && szNew != NULL && szRunning != NULL)
  143. {
  144. szTmp = szRunning;
  145. szRunning = new WCHAR [wcslen(szTmp) + 1 + wcslen(szNew) + 1];
  146. if (szRunning)
  147. {
  148. if (szTmp)
  149. {
  150. wcscpy(szRunning, szTmp);
  151. wcscat(szRunning, szNew);
  152. }
  153. else
  154. {
  155. wcscpy(szRunning, szNew);
  156. }
  157. }
  158. else
  159. {
  160. hr = E_OUTOFMEMORY;
  161. }
  162. delete szTmp;
  163. delete szNew;
  164. if (hr != NOERROR)
  165. {
  166. goto OnErrorExit;
  167. }
  168. }
  169. else
  170. {
  171. szRunning = szNew;
  172. }
  173. pNode = pNode->GetNextNode();
  174. }
  175. *pszAdditionalRequestHeaders = szRunning;
  176. if (hr == E_NOTIMPL)
  177. {
  178. hr = NOERROR;
  179. }
  180. OnErrorExit:
  181. UrlMkDebugOut((DEB_BINDING, "%p OUT CHttpNegHolder::OnError\n", this));
  182. return hr;
  183. }
  184. //+---------------------------------------------------------------------------
  185. //
  186. // Method: CHttpNegHolder::AddNode
  187. //
  188. // Synopsis:
  189. //
  190. // Arguments: [pIHttpNeg] --
  191. //
  192. // Returns:
  193. //
  194. // History:
  195. //
  196. // Notes:
  197. //
  198. //----------------------------------------------------------------------------
  199. HRESULT CHttpNegHolder::AddNode(IHttpNegotiate *pIHttpNeg)
  200. {
  201. UrlMkDebugOut((DEB_BINDING, "%p _IN CHttpNegHolder::AddNode \n", this));
  202. HRESULT hr = NOERROR;
  203. CHttpNegNode *pFirstNode = _pCHttpNegNode;
  204. CHttpNegNode *pNode;
  205. // Allocate memory for new pNode member.
  206. pNode = new CHttpNegNode(pIHttpNeg);
  207. if (!pNode)
  208. {
  209. hr = E_OUTOFMEMORY;
  210. }
  211. else
  212. {
  213. UrlMkDebugOut((DEB_BINDING, "%p IN CHttpNegHolder::AddNode (New Node:%p, IHttpNeg:%p) \n",
  214. this, pNode,pNode->GetHttpNegotiate() ));
  215. // if a node is already
  216. if (pFirstNode)
  217. {
  218. pNode->SetNextNode(pFirstNode);
  219. }
  220. // the new node is the first node
  221. _pCHttpNegNode = pNode;
  222. _cElements++;
  223. }
  224. UrlMkDebugOut((DEB_BINDING, "%p OUT CHttpNegHolder::AddNode (NewNode:%p, hr:%lx) \n", this, pNode, hr));
  225. return hr;
  226. }
  227. //+---------------------------------------------------------------------------
  228. //
  229. // Method: CHttpNegHolder::RemoveAllNodes
  230. //
  231. // Synopsis:
  232. //
  233. // Arguments:
  234. //
  235. // Returns:
  236. //
  237. // History:
  238. //
  239. // Notes:
  240. //
  241. //----------------------------------------------------------------------------
  242. HRESULT CHttpNegHolder::RemoveAllNodes(void)
  243. {
  244. UrlMkDebugOut((DEB_BINDING, "%p _IN CHttpNegHolder::RemoveAllNodes\n", this));
  245. HRESULT hr = S_OK;
  246. CHttpNegNode *pNode = _pCHttpNegNode;
  247. CHttpNegNode *pNextNode = NULL;
  248. while (pNode)
  249. {
  250. pNextNode = pNode->GetNextNode();
  251. // release the object
  252. pNode->GetHttpNegotiate()->Release();
  253. UrlMkDebugOut((DEB_BINDING, "%p OUT CHttpNegHolder::RemoveAllNodes (Delete Node:%p, IHttpNeg:%p) \n",
  254. this, pNode, pNode->GetHttpNegotiate()));
  255. delete pNode;
  256. _cElements--;
  257. pNode = pNextNode;
  258. }
  259. _pCHttpNegNode = NULL;
  260. UrlMkAssert((_cElements == 0));
  261. UrlMkDebugOut((DEB_BINDING, "%p OUT CHttpNegHolder::RemoveAllNodes (hr:%lx) \n", this, hr));
  262. return hr;
  263. }
  264.