HX_RESULT HXFileSystemManager::ProcessGetFileObjectPending() { HX_LOG_BLOCK( "HXFileSystemManager::ProcessGetFileObjectPending" ); HX_RESULT theErr = HXR_OK; IUnknown* pUnknownFS = NULL; IUnknown* pUnknownFileObject = NULL; IHXFileSystemObject* pFileSystem = NULL; IHXRequestHandler* pRequestHandler = NULL; IHXPlugin2Handler* pPlugin2Handler = NULL; if (!m_pContext) { return HXR_FAILED; } /* * We might get released (and deleted) in the response object. so * Addref here and Release after the response function is called */ AddRef(); // get the plugin handler if (HXR_OK != m_pContext->QueryInterface(IID_IHXPlugin2Handler, (void**)&pPlugin2Handler)) { theErr = HXR_FAILED; goto exit; } const char* pURL; HX_ASSERT( NULL != m_pRequest ); if ( ( NULL == m_pRequest ) || ( m_pRequest->GetURL(pURL) != HXR_OK ) ) { theErr = HXR_FAILED; goto exit; } const char* pProtocolEnd; pProtocolEnd = HXFindChar(pURL,':'); if (!pProtocolEnd) { theErr = HXR_FAILED; } if (!theErr) { int nLength = pProtocolEnd - pURL; CHXString strProtocol(pURL,nLength); if (HXR_OK != (theErr = pPlugin2Handler->FindPluginUsingStrings(PLUGIN_CLASS, PLUGIN_FILESYSTEM_TYPE, PLUGIN_FILESYSTEMPROTOCOL, (char*)(const char*)strProtocol, NULL, NULL, pUnknownFS))) { goto exit; } IHXPlugin* pPluginInterface = NULL; if(!theErr) { theErr = pUnknownFS->QueryInterface(IID_IHXPlugin, (void**)&pPluginInterface); } if(!theErr) { theErr = pPluginInterface->InitPlugin(m_pContext); pPluginInterface->Release(); } if(!theErr) { theErr = pUnknownFS->QueryInterface(IID_IHXFileSystemObject, (void**)&pFileSystem); } // At this point we should initalize the file system.to do this we must find the // IHXValues for this mount path in the Options Cache. IHXValues* pOptions = NULL; pOptions = GetOptionsGivenURL(pURL); pFileSystem->InitFileSystem(pOptions); HX_RELEASE(pOptions); if(!theErr) { theErr = pFileSystem->CreateFile(&pUnknownFileObject); } if(!theErr) { if(HXR_OK == pUnknownFileObject->QueryInterface( IID_IHXRequestHandler, (void**)&pRequestHandler)) { pRequestHandler->SetRequest(m_pRequest); } else { theErr = HXR_FAILED; } } } else { theErr = HXR_FAILED; } if (!theErr && pUnknownFileObject) { m_pFSManagerResponse->FileObjectReady(HXR_OK, pUnknownFileObject); } else { m_pFSManagerResponse->FileObjectReady(HXR_FAILED, NULL); } exit: HX_RELEASE(pUnknownFS); HX_RELEASE(pUnknownFileObject); HX_RELEASE(pRequestHandler); HX_RELEASE(pFileSystem); HX_RELEASE(pPlugin2Handler); #ifndef _MACINTOSH // Note: This change is necessary for the Macintosh build due to the fact // that this platform uses a different approach in GetFileObject. The problem // is that file object processing had generally been done recursively, with // GetFileObject calling ProcessGetFileObjectPending, which in turn indirectly // invoked GetFileObject in a pattern of mutual recursion. The recursion had // always ended with a call to ProcessGetFileObjectPending. With the change // in GetFileObject: // #ifdef _MACINTOSH // if (!IsMacInCooperativeThread()) // the recursion would terminate in a GetFileObject call. This call would // unwind to the scheduler, which would then process the queued file object // by calling ProcessGetFileObjectPending. However, since the request object // was freed during the unwinding of the recursion, this object was no longer // available and hence the process failed. // // The best short term fix appears to be to remove this release. The best long // term fix is to eliminate the recursion (which would also simplify maintenance). // -cconover XXX HX_RELEASE(m_pRequest); #endif /* * Release for extra Addref */ Release(); return theErr; }
STDMETHODIMP HXCommonClassFactory::CreateInstance ( REFCLSID /*IN*/ rclsid, void** /*OUT*/ ppUnknown ) { if (IsEqualCLSID(rclsid, CLSID_IHXBuffer)) { *ppUnknown = (IUnknown*)(IHXBuffer*)(new ServerBuffer(TRUE)); return HXR_OK; } else if (IsEqualCLSID(rclsid, CLSID_IHXPacket)) { if (!g_bFastMallocAll && !g_bFastMalloc) *ppUnknown = (IUnknown*)(IHXPacket*)(new ServerPacket(TRUE)); else *ppUnknown = (IUnknown*)(IHXPacket*)(new(m_pMemCache) ServerPacket(TRUE)); return HXR_OK; } else if (IsEqualCLSID(rclsid, CLSID_IHXRTPPacket)) { if (!g_bFastMallocAll && !g_bFastMalloc) *ppUnknown = (IUnknown*)(IHXRTPPacket*)(new ServerRTPPacket(TRUE)); else *ppUnknown = (IUnknown*)(IHXRTPPacket*)(new(m_pMemCache) ServerRTPPacket(TRUE)); return HXR_OK; } else if (IsEqualCLSID(rclsid, CLSID_IHXValues)) { *ppUnknown = (IUnknown*)(IHXValues*)(new CHXHeader()); ((IUnknown*)*ppUnknown)->AddRef(); return HXR_OK; } else if (IsEqualCLSID(rclsid, CLSID_IHXValues2)) { *ppUnknown = (IUnknown*)(IHXValues2*)(new CHXHeader()); ((IUnknown*)*ppUnknown)->AddRef(); return HXR_OK; } else if (IsEqualCLSID(rclsid, CLSID_IHXFileSystemManager)) { *ppUnknown = (IUnknown*)(IHXFileSystemManager*)(new FSManager(m_proc)); ((IUnknown*)*ppUnknown)->AddRef(); return HXR_OK; } else if(IsEqualCLSID(rclsid, CLSID_IHXPluginGroupEnumerator)) { *ppUnknown = (IUnknown*)(IHXPluginGroupEnumerator*) (new CHXPluginGroupEnumerator(m_proc->pc->plugin_handler)); ((IUnknown*)*ppUnknown)->AddRef(); return HXR_OK; } else if (IsEqualCLSID(rclsid, CLSID_IHXFragmentedBuffer)) { *ppUnknown = (IUnknown*)(IHXFragmentedBuffer*)(new CHXFragmentedBuffer((IUnknown*)(IHXCommonClassFactory*)this)); ((IUnknown*)*ppUnknown)->AddRef(); return HXR_OK; } else if (IsEqualCLSID(rclsid, CLSID_IHXKeyValueList)) { *ppUnknown = (IUnknown*)(IHXKeyValueList*)(new CKeyValueList()); ((IUnknown*)*ppUnknown)->AddRef(); return HXR_OK; } else if (IsEqualIID(rclsid, CLSID_IHXSourceFinderObject)) { *ppUnknown = (IUnknown*)(IHXSourceFinderObject*)(new CServerSourceFinder(m_proc)); ((IUnknown*)*ppUnknown)->AddRef(); return HXR_OK; } else if (IsEqualCLSID(rclsid, CLSID_IHXHTTPPostObject)) { CHXHTTPPostObject* pObject = CHXHTTPPostObject::CreateObject(); *ppUnknown = (IUnknown*) (IHXHTTPPostObject*) pObject; ((IUnknown*)*ppUnknown)->AddRef(); pObject->InitObject(m_proc->pc->server_context); return HXR_OK; } else if(IsEqualCLSID(rclsid, CLSID_IHXRequest)) { *ppUnknown = (IUnknown*)(IHXRequest*)(new CHXRequest()); ((IUnknown*)*ppUnknown)->AddRef(); return HXR_OK; } else if (IsEqualCLSID(rclsid, CLSID_IHXMutex)) { *ppUnknown = (IUnknown*)(IHXMutex*)(new Mutex()); ((IUnknown*)*ppUnknown)->AddRef(); return HXR_OK; } else if (IsEqualCLSID(rclsid, CLSID_IHXFastFileFactory)) { *ppUnknown = (IUnknown*)(IHXFastFileFactory*) (new FastFileFactory(m_proc->pc->server_context)); ((IUnknown*)*ppUnknown)->AddRef(); return HXR_OK; } else if (IsEqualCLSID(rclsid, CLSID_IHXFastFileFactory2)) { *ppUnknown = (IUnknown*)(IHXFastFileFactory2*) (new FastFileFactory(m_proc->pc->server_context)); ((IUnknown*)*ppUnknown)->AddRef(); return HXR_OK; } else if (IsEqualCLSID(rclsid, CLSID_IHXQoSSignal)) { *ppUnknown = (IUnknown*)(IHXQoSSignal*)(new QoSSignal()); ((IUnknown*)*ppUnknown)->AddRef(); return HXR_OK; } else if (IsEqualCLSID(rclsid, CLSID_IHXList)) { IHXFastAlloc* pAlloc = NULL; m_proc->pc->server_context->QueryInterface(IID_IHXFastAlloc, (void**)&pAlloc); *ppUnknown = (IUnknown*)(IHXList*)(new CHXList(pAlloc)); ((IUnknown*)*ppUnknown)->AddRef(); return HXR_OK; } else if(IsEqualCLSID(rclsid, IID_IHXPacketOrderer)) { *ppUnknown = (IUnknown*)(IHXPacketOrderer*)(new CPacketOrderShim()); ((IUnknown*)*ppUnknown)->AddRef(); return HXR_OK; } else { // Try the factory plugins PluginHandler* pPluginHandler = m_proc->pc->plugin_handler; *ppUnknown = NULL; if(pPluginHandler) { PluginHandler::Factory* pFactories; PluginHandler::Plugin* pPlugin; CHXSimpleList::Iterator i; pFactories = pPluginHandler->m_factory_handler; for(i = pFactories->m_pPlugins->Begin(); i != pFactories->m_pPlugins->End(); ++i) { IUnknown* pInstance = 0; pPlugin = (PluginHandler::Plugin*)(*i); pPlugin->GetInstance(&pInstance); if(pInstance) { HX_RESULT res; IHXPlugin* pFPlugin = 0; res = pInstance->QueryInterface(IID_IHXPlugin, (void**)&pFPlugin); if(res == HXR_OK) { IHXCommonClassFactory* pClassFactory; IUnknown* pContext; m_proc->pc->server_context->QueryInterface( IID_IUnknown, (void**)&pContext); pFPlugin->InitPlugin(pContext); pFPlugin->Release(); pContext->Release(); res = pInstance->QueryInterface( IID_IHXCommonClassFactory, (void**)&pClassFactory); if(HXR_OK == res) { res = pClassFactory->CreateInstance(rclsid, ppUnknown); if(HXR_OK != res) *ppUnknown = NULL; pClassFactory->Release(); } } pInstance->Release(); pPlugin->ReleaseInstance(); if(*ppUnknown) { return HXR_OK; } } } } } *ppUnknown = NULL; return HXR_NOINTERFACE; }
void DataRevertController::RevertHeaders(IHXValues* pFileHeader, CHXSimpleList* pStreamHeaders, IHXValues* pResponseHeaders) { IHXBuffer* pMimeType = 0; IHXValues* pHeader; CHXSimpleList::Iterator i; char* pConversionType = NULL; IUnknown* pUnkReverter = NULL; HX_RELEASE(m_pDataRevert); i = pStreamHeaders->Begin(); if (i != pStreamHeaders->End()) { pHeader = (IHXValues*)(*i); pHeader->GetPropertyCString("MimeType", pMimeType); if (!pMimeType) { HX_ASSERT(0); goto exit; } if (strncasecmp((const char*)pMimeType->GetBuffer(), HX_CONVERT_MIME_TYPE, (int)strlen(HX_CONVERT_MIME_TYPE))) { goto exit; } pConversionType = (char*)pMimeType->GetBuffer() + strlen(HX_CONVERT_MIME_TYPE); if (m_pPlugin2Handler && HXR_OK == m_pPlugin2Handler->FindPluginUsingStrings( PLUGIN_CLASS, PLUGIN_REVERTER_TYPE, PLUGIN_REVERTER_MIME, pConversionType, NULL, NULL, pUnkReverter)) { pUnkReverter->QueryInterface(IID_IHXDataRevert, (void**)&m_pDataRevert); pUnkReverter->Release(); } if (!m_pDataRevert) { goto exit; } IHXPlugin* pPlugin; m_pDataRevert->QueryInterface(IID_IHXPlugin, (void**)&pPlugin); pPlugin->InitPlugin(m_pContext); pPlugin->Release(); HX_RELEASE(pMimeType); m_pStreamHeaders = new CHXSimpleList; m_pRevertedStreamHeaders = new CHXSimpleList; IHXBuffer* pConvertHeader = 0; for (i = pStreamHeaders->Begin(); i != pStreamHeaders->End(); ++i) { pHeader = (IHXValues*)(*i); /* * If this stream header was converted and flattened then * the one we want to give to the plugin is the result * of re-inflating that. If not, then just give the plugin * the one we already got. */ if (HXR_OK == pHeader->GetPropertyBuffer("DataConvertStreamHeader", pConvertHeader)) { pHeader = InflateConvertHeader(pConvertHeader); pConvertHeader->Release(); } else { IHXBuffer* pPreConvertMimeType; if (HXR_OK == pHeader->GetPropertyCString("PreConvertMimeType", pPreConvertMimeType)) { pHeader->SetPropertyCString("MimeType", pPreConvertMimeType); pPreConvertMimeType->Release(); } pHeader->AddRef(); } m_pStreamHeaders->AddTail((void*)pHeader); } m_pResponseHeaders = pResponseHeaders; m_pResponseHeaders->AddRef(); /* * If playing through an old proxy which does not support * initiate-session then the DataConvertBuffer will come in here. * This is not an ideal situation because only one can come in * at this point, but it's better then nothing. */ IHXBuffer* pConvertBuffer = 0; if (HXR_OK == pFileHeader->GetPropertyBuffer("DataConvertBuffer", pConvertBuffer)) { const char* pContent = (const char*)pConvertBuffer->GetBuffer(); IHXBuffer* pNewBuffer = NULL; if (HXR_OK == CreateBufferCCF(pNewBuffer, m_pContext)) { int contentLen = pConvertBuffer->GetSize(); pNewBuffer->SetSize(contentLen); int offset = BinFrom64(pContent, contentLen, (unsigned char*)pNewBuffer->GetBuffer()); pNewBuffer->SetSize(offset); ControlBufferReady(pNewBuffer); HX_RELEASE(pNewBuffer); } HX_RELEASE(pConvertBuffer); } /* * Again for file header, if the header was converted and * flattened then give to plugin the inflated version of that. * If not, then give the straight old header that we already * have. */ if (HXR_OK == pFileHeader->GetPropertyBuffer("DataConvertFileHeader", pConvertHeader)) { m_pFileHeaders = InflateConvertHeader(pConvertHeader); pConvertHeader->Release(); } else { m_pFileHeaders = pFileHeader; m_pFileHeaders->AddRef(); } m_pDataRevert->DataRevertInit(this); return; } exit:; HX_RELEASE(pMimeType); m_pControlResp->RevertHeadersDone(pFileHeader, pStreamHeaders, pResponseHeaders, FALSE); }