/************************************************************************ * Method: * IHXPacketHookManager::StartHook * Purpose: * called by the top level client to start recording */ STDMETHODIMP PacketHookManager::StartHook () { HX_RESULT hr = HXR_OK; UINT16 i = 0; UINT16 j = 0; UINT16 k = 0; UINT16 ulSources = 0; UINT16 ulStreams = 0; UINT16 ulStreamIndex = 0; IHXBuffer* pTitle = NULL; IHXBuffer* pAuthor = NULL; IHXBuffer* pCopyright = NULL; IHXValues* pFileHeader = NULL; IHXValues* pStreamHeader = NULL; IUnknown* pUnknown = NULL; IHXPrivateStreamSource *pPrivateSource = NULL; // for IsSaveAllowed, take this out; XXXCP IHXStreamSource* pSource = NULL; IHXInfoLogger* pInfoLogger = NULL; // make sure everything has been initialized if (!m_pPlayer || !m_pPacketHook) { hr = HXR_FAILED; goto cleanup; } // caculate the total number of streams + TAC info. if (!(ulSources = m_pPlayer->GetSourceCount())) { hr = HXR_FAILED; goto cleanup; } m_ulTotalStreams = 0; for (i = 0; i < ulSources; i++) { if (HXR_OK != m_pPlayer->GetSource(i, pUnknown)) { continue; } if (HXR_OK != pUnknown->QueryInterface(IID_IHXStreamSource, (void**)&pSource)) { HX_RELEASE(pUnknown); continue; } if (HXR_OK == pUnknown->QueryInterface(IID_IHXPrivateStreamSource, (void**)&pPrivateSource)) { if (!(pPrivateSource->IsSaveAllowed())) { pPrivateSource->Release(); continue; } pPrivateSource->Release(); } m_ulTotalStreams += pSource->GetStreamCount(); HX_RELEASE(pSource); HX_RELEASE(pUnknown); } if (!m_ulTotalStreams) { hr = HXR_FAILED; goto cleanup; } // prepare the file header CreateBufferCCF(pTitle, m_pPlayer); CreateBufferCCF(pAuthor, m_pPlayer); CreateBufferCCF(pCopyright, m_pPlayer); // XXX HP: find better way to collect TAC info #define szTitle "title" #define szAuthor "author" #define szCopyright "copyright" pTitle->Set((const unsigned char*)szTitle, strlen(szTitle)+1); pAuthor->Set((const unsigned char*)szAuthor, strlen(szAuthor)+1); pCopyright->Set((const unsigned char*)szCopyright, strlen(szCopyright)+1); if (HXR_OK == CreateValuesCCF(pFileHeader, m_pPlayer)) { // set attributes(i.e. num. of streams + TAC) pFileHeader->SetPropertyBuffer("Title", pTitle); pFileHeader->SetPropertyBuffer("Author", pAuthor); pFileHeader->SetPropertyBuffer("Copyright", pCopyright); pFileHeader->SetPropertyULONG32("StreamCount", m_ulTotalStreams); } // signal the top level client of upcoming content m_pPacketHook->OnStart(); // send file header to its top level client hr = m_pPacketHook->OnFileHeader(pFileHeader); if (hr != HXR_OK) { HX_RELEASE(m_pPacketHook); goto cleanup; } // prepare the stream headers m_ulRecordableStreams = 0; ulStreamIndex = 0; for (i = 0; i < ulSources; i++) { if (HXR_OK != m_pPlayer->GetSource(i, pUnknown)) { HX_RELEASE(pUnknown); continue; } if (HXR_OK != pUnknown->QueryInterface(IID_IHXStreamSource, (void**)&pSource)) { HX_RELEASE(pSource); continue; } if (HXR_OK == pUnknown->QueryInterface(IID_IHXPrivateStreamSource, (void**)&pPrivateSource)) { if (!(pPrivateSource->IsSaveAllowed())) { pPrivateSource->Release(); continue; } pPrivateSource->Release(); } if (HXR_OK == pUnknown->QueryInterface(IID_IHXInfoLogger, (void**)&pInfoLogger)) { pInfoLogger->LogInformation("RECSTART", NULL); } HX_RELEASE(pInfoLogger); ulStreams = pSource->GetStreamCount(); for (j = 0; j < ulStreams; j++) { const char* pszPropName = NULL; UINT16 ulRenderers = 0; ULONG32 ulPropValue = 0; HXBOOL bRecordable = FALSE; IHXValues* pHeader = NULL; IHXBuffer* pPropValueSource = NULL; IHXBuffer* pPropValueTarget = NULL; IHXStream* pStream = NULL; // retrieve the stream info pSource->GetStream(j, (IUnknown*&)pStream); pHeader = pStream->GetHeader(); // make a copy of this stream header // XXX HP: this could be wrapped up into one method in CHXHeader CreateValuesCCF(pStreamHeader, m_pPlayer); // copy all the ULONG32 attributes if (HXR_OK == pHeader->GetFirstPropertyULONG32(pszPropName, ulPropValue)) { pStreamHeader->SetPropertyULONG32(pszPropName, ulPropValue); while (HXR_OK == pHeader->GetNextPropertyULONG32(pszPropName, ulPropValue)) { pStreamHeader->SetPropertyULONG32(pszPropName, ulPropValue); } } // copy all the buffer attributes if (HXR_OK == pHeader->GetFirstPropertyBuffer(pszPropName, (IHXBuffer*&)pPropValueSource)) { if (HXR_OK == CreateAndSetBufferCCF(pPropValueTarget, pPropValueSource->GetBuffer(), pPropValueSource->GetSize(), m_pPlayer)) { pStreamHeader->SetPropertyBuffer(pszPropName, pPropValueTarget); HX_RELEASE(pPropValueTarget); } HX_RELEASE(pPropValueSource); while (HXR_OK == pHeader->GetNextPropertyBuffer(pszPropName, (IHXBuffer*&)pPropValueSource)) { if (HXR_OK == CreateAndSetBufferCCF(pPropValueTarget, pPropValueSource->GetBuffer(), pPropValueSource->GetSize(), m_pPlayer)) { pStreamHeader->SetPropertyBuffer(pszPropName, pPropValueTarget); HX_RELEASE(pPropValueTarget); } HX_RELEASE(pPropValueSource); } } // copy all the CString attributes if (HXR_OK == pHeader->GetFirstPropertyCString(pszPropName, (IHXBuffer*&)pPropValueSource)) { if (HXR_OK == CreateAndSetBufferCCF(pPropValueTarget, pPropValueSource->GetBuffer(), pPropValueSource->GetSize(), m_pPlayer)) { pStreamHeader->SetPropertyCString(pszPropName, pPropValueTarget); HX_RELEASE(pPropValueTarget); } HX_RELEASE(pPropValueSource); while (HXR_OK == pHeader->GetNextPropertyCString(pszPropName, (IHXBuffer*&)pPropValueSource)) { if (HXR_OK == CreateAndSetBufferCCF(pPropValueTarget, pPropValueSource->GetBuffer(), pPropValueSource->GetSize(), m_pPlayer)) { pStreamHeader->SetPropertyCString(pszPropName, pPropValueTarget); HX_RELEASE(pPropValueTarget); } HX_RELEASE(pPropValueSource); } } HX_RELEASE(pHeader); // modify some values pStreamHeader->SetPropertyULONG32("StreamNumber", ulStreamIndex); // the stream is recordable as long as there is one renderer supports // IHXPacketHookHelper. Multiple renderers can serve the packets with // the same stream number on it, One solution for this is to choose the // first renderer which supports IHXPacketHookHelper as the only source ulRenderers = pStream->GetRendererCount(); for (k = 0; k < ulRenderers; k++) { IUnknown* pUnknown = NULL; IHXPacketHookHelper* pPacketHookHelper = NULL; pStream->GetRenderer(k, pUnknown); if (HXR_OK == pUnknown->QueryInterface(IID_IHXPacketHookHelper, (void**)&pPacketHookHelper)) { bRecordable = TRUE; pPacketHookHelper->StartHook(ulStreamIndex, 0, new PacketHookHelperResponse(this, ulStreamIndex)); } HX_RELEASE(pPacketHookHelper); HX_RELEASE(pUnknown); } if (bRecordable) { m_ulRecordableStreams++; } pStreamHeader->SetPropertyULONG32("Recordable", (ULONG32)bRecordable); /* * It's possible that StartHook will cause the m_pPacketHook to * be released */ if (!m_pPacketHook) { hr = HXR_UNEXPECTED; goto cleanup; } // send stream header to its top level client hr = m_pPacketHook->OnStreamHeader(pStreamHeader); if (hr != HXR_OK) { HX_RELEASE(m_pPacketHook); goto cleanup; } ulStreamIndex++; HX_RELEASE(pStreamHeader); HX_RELEASE(pStream); } HX_RELEASE(pSource); HX_RELEASE(pUnknown); } cleanup: HX_RELEASE(pTitle); HX_RELEASE(pAuthor); HX_RELEASE(pCopyright); HX_RELEASE(pFileHeader); return hr; }
STDMETHODIMP HXCloakedV2TCPSocket::ResponseReady( HX_RESULT res, IHXRequest* pRequestResponse) { IHXCommonClassFactory* pCCF = NULL; IHXRegistry* pRegistry = NULL; IHXValues* pHeaders = NULL; const char* pName = NULL; IHXBuffer* pBuf = NULL; CHXString key = ""; IHXBuffer* pTmpBuffer = NULL; if( SUCCEEDED(res) ) { //Extract the authentication info, again, this is a real waste to just //get a username password. See comment in _DoProxyAuthentication. res = m_pContext->QueryInterface(IID_IHXCommonClassFactory, (void**)&pCCF); if( SUCCEEDED(res) ) { res = m_pContext->QueryInterface(IID_IHXRegistry, (void**)&pRegistry); if( SUCCEEDED(res) ) { res = pRequestResponse->GetRequestHeaders(pHeaders); if( SUCCEEDED(res) ) { res = pHeaders->GetFirstPropertyCString(pName, pBuf); while( SUCCEEDED(res) && pBuf ) { if( !strcasecmp(pName, "Proxy-Authorization") ) { CHXString key = "proxy-authentication.http:"; key += m_pszProxyName; key += ":"; res = pRegistry->GetStrByName( "proxy-authentication.http.realm.recent", pTmpBuffer); if( SUCCEEDED(res) ) { key += CHXString((const char*)pTmpBuffer->GetBuffer(), pTmpBuffer->GetSize()); } HX_RELEASE(pTmpBuffer); res = pCCF->CreateInstance(CLSID_IHXBuffer, (void**)&pTmpBuffer); if( SUCCEEDED(res) ) { pTmpBuffer->Set(pBuf->GetBuffer(), pBuf->GetSize()); UINT32 regid = pRegistry->GetId((const char*)key); if (!regid) { pRegistry->AddStr((const char*)key, pTmpBuffer); } else { pRegistry->SetStrByName((const char*)key, pTmpBuffer); } } HX_RELEASE(pTmpBuffer); break; } // get next header name value line HX_RELEASE(pBuf); res = pHeaders->GetNextPropertyCString(pName, pBuf); } HX_RELEASE(pBuf); HX_RELEASE(pHeaders); } } HX_RELEASE(pRegistry); } HX_RELEASE(pCCF); } HX_RELEASE(pRequestResponse); //We need to start over connting again.... m_CloakingState = csDisconnected; if( m_pTCPSocket) { m_pTCPSocket->Close(); HX_RELEASE(m_pTCPSocket); } res = m_pNetworkServices->CreateSocket(&m_pTCPSocket); if(m_pTCPSocket && SUCCEEDED(res) ) { res = m_pTCPSocket->SetResponse(this); if( SUCCEEDED(res) ) { res = m_pTCPSocket->Init(m_family, m_type, m_protocol); m_pTCPSocket->SetOption( HX_SOCKOPT_APP_BUFFER_TYPE, HX_SOCKBUF_DEFAULT); m_pTCPSocket->SelectEvents(HX_SOCK_EVENT_READ| HX_SOCK_EVENT_CONNECT| HX_SOCK_EVENT_CLOSE); res = m_pTCPSocket->ConnectToOne(m_pDestAddr); } } return res; }