//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1992 - 1996. // // File: HTTPNEG.CXX // // Contents: Code to handle multiplexing multiple concurrent // IHttpNegotiate interfaces. // // Classes: CHttpNegHolder // // Functions: // // History: 01-30-96 JoeS (Joe Souza) Created // //---------------------------------------------------------------------------- #include #include #include "httpneg.hxx" CHttpNegHolder::CHttpNegHolder(void) : _CRefs() { _pCHttpNegNode = NULL; _cElements = 0; } STDMETHODIMP CHttpNegHolder::QueryInterface(REFIID riid, void **ppvObj) { VDATEPTROUT(ppvObj, void *); VDATETHIS(this); HRESULT hr = NOERROR; UrlMkDebugOut((DEB_BINDING, "%p _IN CHttpNegHolder::QueryInterface\n", this)); *ppvObj = NULL; if (riid == IID_IHttpNegotiate) { *ppvObj = this; AddRef(); } else { hr = E_NOINTERFACE; CHttpNegNode *pNode; pNode = _pCHttpNegNode; while (pNode) { hr = pNode->GetHttpNegotiate()->QueryInterface(riid, ppvObj); if (hr == NOERROR) { pNode = NULL; } else { pNode = pNode->GetNextNode(); } } } UrlMkDebugOut((DEB_BINDING, "%p OUT CHttpNegHolder::QueryInterface (hr:%lx\n", this,hr)); return hr; } STDMETHODIMP_(ULONG) CHttpNegHolder::AddRef(void) { UrlMkDebugOut((DEB_BINDING, "%p _IN CHttpNegHolder::AddRef\n", this)); LONG lRet = ++_CRefs; UrlMkDebugOut((DEB_BINDING, "%p OUT CHttpNegHolder::AddRef (cRefs:%ld)\n", this,lRet)); return lRet; } STDMETHODIMP_(ULONG) CHttpNegHolder::Release(void) { UrlMkDebugOut((DEB_BINDING, "%p _IN CHttpNegHolder::Release\n", this)); UrlMkAssert((_CRefs > 0)); LONG lRet = --_CRefs; if (_CRefs == 0) { RemoveAllNodes(); delete this; } UrlMkDebugOut((DEB_BINDING, "%p OUT CHttpNegHolder::Release (cRefs:%ld)\n",this,lRet)); return lRet; } HRESULT CHttpNegHolder::BeginningTransaction(LPCWSTR szURL, LPCWSTR szHeaders, DWORD dwReserved, LPWSTR *pszAdditionalHeaders) { UrlMkDebugOut((DEB_BINDING, "%p _IN CHttpNegHolder::BeginningTransaction (szURL:%ws, szHeaders:%ws)\n", this, szURL, szHeaders)); VDATETHIS(this); HRESULT hr = NOERROR; CHttpNegNode *pNode; LPWSTR szTmp = NULL, szNew = NULL, szRunning = NULL; pNode = _pCHttpNegNode; while (pNode) { hr = pNode->GetHttpNegotiate()->BeginningTransaction(szURL, szHeaders, dwReserved, &szNew); UrlMkDebugOut((DEB_BINDING, "%p === CHttpNegHolder::BeginningTransaction (szNew:%ws )\n", this, szNew)); if (hr == NOERROR && szNew != NULL && szRunning != NULL) { szTmp = szRunning; szRunning = new WCHAR [wcslen(szTmp) + 1 + wcslen(szNew) + 1]; if (szRunning) { if (szTmp) { wcscpy(szRunning, szTmp); wcscat(szRunning, szNew); } else { wcscpy(szRunning, szNew); } } else { hr = E_OUTOFMEMORY; } delete szTmp; delete szNew; if (hr != NOERROR) { goto BegTransExit; } } else { szRunning = szNew; } pNode = pNode->GetNextNode(); } *pszAdditionalHeaders = szRunning; BegTransExit: UrlMkDebugOut((DEB_BINDING, "%p OUT CHttpNegHolder::BeginningTransaction (pszAdditionalHeaders:%ws )\n", this, *pszAdditionalHeaders)); return hr; } HRESULT CHttpNegHolder::OnResponse(DWORD dwResponseCode,LPCWSTR szResponseHeaders, LPCWSTR szRequestHeaders,LPWSTR *pszAdditionalRequestHeaders) { UrlMkDebugOut((DEB_BINDING, "%p _IN CHttpNegHolder::OnError\n", this)); VDATETHIS(this); HRESULT hr = NOERROR; CHttpNegNode *pNode; LPWSTR szTmp = NULL, szNew = NULL, szRunning = NULL; pNode = _pCHttpNegNode; while (pNode) { hr = pNode->GetHttpNegotiate()->OnResponse(dwResponseCode, szResponseHeaders, szRequestHeaders, &szNew); if (hr == NOERROR && szNew != NULL && szRunning != NULL) { szTmp = szRunning; szRunning = new WCHAR [wcslen(szTmp) + 1 + wcslen(szNew) + 1]; if (szRunning) { if (szTmp) { wcscpy(szRunning, szTmp); wcscat(szRunning, szNew); } else { wcscpy(szRunning, szNew); } } else { hr = E_OUTOFMEMORY; } delete szTmp; delete szNew; if (hr != NOERROR) { goto OnErrorExit; } } else { szRunning = szNew; } pNode = pNode->GetNextNode(); } *pszAdditionalRequestHeaders = szRunning; if (hr == E_NOTIMPL) { hr = NOERROR; } OnErrorExit: UrlMkDebugOut((DEB_BINDING, "%p OUT CHttpNegHolder::OnError\n", this)); return hr; } //+--------------------------------------------------------------------------- // // Method: CHttpNegHolder::AddNode // // Synopsis: // // Arguments: [pIHttpNeg] -- // // Returns: // // History: // // Notes: // //---------------------------------------------------------------------------- HRESULT CHttpNegHolder::AddNode(IHttpNegotiate *pIHttpNeg) { UrlMkDebugOut((DEB_BINDING, "%p _IN CHttpNegHolder::AddNode \n", this)); HRESULT hr = NOERROR; CHttpNegNode *pFirstNode = _pCHttpNegNode; CHttpNegNode *pNode; // Allocate memory for new pNode member. pNode = new CHttpNegNode(pIHttpNeg); if (!pNode) { hr = E_OUTOFMEMORY; } else { UrlMkDebugOut((DEB_BINDING, "%p IN CHttpNegHolder::AddNode (New Node:%p, IHttpNeg:%p) \n", this, pNode,pNode->GetHttpNegotiate() )); // if a node is already if (pFirstNode) { pNode->SetNextNode(pFirstNode); } // the new node is the first node _pCHttpNegNode = pNode; _cElements++; } UrlMkDebugOut((DEB_BINDING, "%p OUT CHttpNegHolder::AddNode (NewNode:%p, hr:%lx) \n", this, pNode, hr)); return hr; } //+--------------------------------------------------------------------------- // // Method: CHttpNegHolder::RemoveAllNodes // // Synopsis: // // Arguments: // // Returns: // // History: // // Notes: // //---------------------------------------------------------------------------- HRESULT CHttpNegHolder::RemoveAllNodes(void) { UrlMkDebugOut((DEB_BINDING, "%p _IN CHttpNegHolder::RemoveAllNodes\n", this)); HRESULT hr = S_OK; CHttpNegNode *pNode = _pCHttpNegNode; CHttpNegNode *pNextNode = NULL; while (pNode) { pNextNode = pNode->GetNextNode(); // release the object pNode->GetHttpNegotiate()->Release(); UrlMkDebugOut((DEB_BINDING, "%p OUT CHttpNegHolder::RemoveAllNodes (Delete Node:%p, IHttpNeg:%p) \n", this, pNode, pNode->GetHttpNegotiate())); delete pNode; _cElements--; pNode = pNextNode; } _pCHttpNegNode = NULL; UrlMkAssert((_cElements == 0)); UrlMkDebugOut((DEB_BINDING, "%p OUT CHttpNegHolder::RemoveAllNodes (hr:%lx) \n", this, hr)); return hr; }