📄 hxfsmgr.cpp
字号:
IHXAuthenticator* pAuthenticator){ HX_LOG_BLOCK( "HXFileSystemManager::GetFileObject" ); HX_RESULT theErr = HXR_OK; HX_RELEASE(m_pRequest); m_pRequest = pRequest; if (m_pRequest) { m_pRequest->AddRef(); } m_State = e_GetFileObjectPending;#ifdef _MACINTOSH if (!IsMacInCooperativeThread()) { if (!m_pScheduler) { HX_VERIFY(m_pContext->QueryInterface(IID_IHXScheduler, (void**) &m_pScheduler) == HXR_OK); } if (!m_pCallback) { m_pCallback = new RMAFSManagerCallback(this); m_pCallback->AddRef(); } HX_ASSERT(m_pCallback->m_bIsCallbackPending == FALSE); if (!m_pCallback->m_bIsCallbackPending) { m_pCallback->m_bIsCallbackPending = TRUE; m_pCallback->m_Handle = m_pScheduler->RelativeEnter(m_pCallback, 0); } return HXR_OK; }#endif return (ProcessGetFileObjectPending());}HX_RESULTHXFileSystemManager::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;}/* * In this implementation of FSManager, GetNewFileObject is wholly * equivalent to GetFileObject. GetNewFileObject exists for the * server's FSManager since it would otherwise be impossible to get * a brand new file object for writing, as the DoesExist checks * would fail for every file system checked. This implementation has * ambiguities between URL's and file systems, so there is no * different functionality needed. */STDMETHODIMPHXFileSystemManager::GetNewFileObject(IHXRequest* pRequest, IHXAuthenticator* pAuthenticator){ return GetFileObject(pRequest, pAuthenticator);}STDMETHODIMPHXFileSystemManager::GetRelativeFileObject(IUnknown* pOriginalObject, const char* pRelativePath){ HX_RESULT theErr = HXR_OK; if(!pRelativePath) { return HXR_FAIL; } HX_RELEASE(m_pOriginalObject); m_pOriginalObject = pOriginalObject; if (m_pOriginalObject) { m_pOriginalObject->AddRef(); } HX_VECTOR_DELETE(m_pRelativePath); m_pRelativePath = new_string(pRelativePath); m_State = e_GetRelativeFileObjectPending;#ifdef _MACINTOSH if (!IsMacInCooperativeThread()) { if (!m_pScheduler) { HX_VERIFY(m_pContext->QueryInterface(IID_IHXScheduler, (void**) &m_pScheduler) == HXR_OK); } if (!m_pCallback) { m_pCallback = new RMAFSManagerCallback(this); m_pCallback->AddRef(); } HX_ASSERT(m_pCallback->m_bIsCallbackPending == FALSE); if (!m_pCallback->m_bIsCallbackPending) { m_pCallback->m_bIsCallbackPending = TRUE; m_pCallback->m_Handle = m_pScheduler->RelativeEnter(m_pCallback, 0); } return HXR_OK; }#endif return (ProcessGetRelativeFileObjectPending());}HX_RESULTHXFileSystemManager::ProcessGetRelativeFileObjectPending(){ HX_RESULT theErr = HXR_OK; IHXRequestHandler* pRequestHandlerOrigional = NULL; IHXRequest* pRequestOld = NULL; AddRef(); if (!m_pOriginalObject) goto exit; if(HXR_OK != m_pOriginalObject->QueryInterface(IID_IHXGetFileFromSamePool, (void**)&m_pSamePool)) { theErr = HXR_FAIL; goto exit; } if ( HXR_OK != m_pOriginalObject->QueryInterface ( IID_IHXRequestHandler, (void**)&pRequestHandlerOrigional ) || !pRequestHandlerOrigional || HXR_OK != pRequestHandlerOrigional->GetRequest(pRequestOld) || !pRequestOld ) { HX_RELEASE(pRequestHandlerOrigional); HX_RELEASE(pRequestOld); theErr = HXR_FAIL; goto exit; } HX_RELEASE(pRequestHandlerOrigional); /* * Create an IHXRequest object for the new file */ HX_RELEASE(m_pRequest); CHXRequest::CreateFrom(pRequestOld, &m_pRequest); HX_RELEASE(pRequestOld); m_pRequest->SetURL(m_pRelativePath); if(HXR_OK != m_pSamePool->GetFileObjectFromPool(this)) { theErr = HXR_FAIL; goto exit; }exit: HX_RELEASE(m_pSamePool); HX_RELEASE(m_pOriginalObject); HX_VECTOR_DELETE(m_pRelativePath); Release(); return theErr;}STDMETHODIMPHXFileSystemManager::FileObjectReady(HX_RESULT status, IUnknown* pUnknown){ IHXRequestHandler* pRequestHandler = NULL; if(HXR_OK == status) { if(HXR_OK == pUnknown->QueryInterface(IID_IHXRequestHandler, (void**)&pRequestHandler)) { pRequestHandler->SetRequest(m_pRequest); } else { pUnknown = 0; status = HXR_FAILED; } pRequestHandler->Release(); } HX_RELEASE(m_pRequest); /* * We might get released (and deleted) in the response object. so * Addref here and Release after the response function is called */ AddRef(); if (m_pFSManagerResponse) { m_pFSManagerResponse->FileObjectReady(status, pUnknown); } /* * Release for extra Addref */ Release(); return HXR_OK;}STDMETHODIMP HXFileSystemManager::GetDirObjectFromURL(const char* pURL){ return HXR_NOTIMPL;}voidHXFileSystemManager::ProcessPendingRequest(){ switch(m_State) { case e_GetFileObjectPending: ProcessGetFileObjectPending(); break; case e_GetRelativeFileObjectPending: ProcessGetRelativeFileObjectPending(); break; default: HX_ASSERT(FALSE); break; } }// HXFileSystemManager::RMAFSManagerCallbackHXFileSystemManager::RMAFSManagerCallback::RMAFSManagerCallback(HXFileSystemManager* pFSManager) : m_lRefCount (0) ,m_pFSManager (pFSManager) ,m_Handle (0) ,m_bIsCallbackPending(FALSE){}HXFileSystemManager::RMAFSManagerCallback::~RMAFSManagerCallback(){}/* * IUnknown methods *//////////////////////////////////////////////////////////////////////////// Method:// IUnknown::QueryInterface// Purpose:// Implement this to export the interfaces supported by your // object.//STDMETHODIMP HXFileSystemManager::RMAFSManagerCallback::QueryInterface(REFIID riid, void** ppvObj){ QInterfaceList qiList[] = { { GET_IIDHANDLE(IID_IHXCallback), (IHXCallback*)this }, { GET_IIDHANDLE(IID_IUnknown), (IUnknown*)(IHXCallback*)this }, }; return ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);}/////////////////////////////////////////////////////////////////////////// Method:// IUnknown::AddRef// Purpose:// Everyone usually implements this the same... feel free to use// this implementation.//STDMETHODIMP_(ULONG32) HXFileSystemManager::RMAFSManagerCallback::AddRef(){ return InterlockedIncrement(&m_lRefCount);}/////////////////////////////////////////////////////////////////////////// Method:// IUnknown::Release// Purpose:// Everyone usually implements this the same... feel free to use// this implementation.//STDMETHODIMP_(ULONG32) HXFileSystemManager::RMAFSManagerCallback::Release(){ if (InterlockedDecrement(&m_lRefCount) > 0) { return m_lRefCount; } delete this; return 0;}/* * UDPSchedulerCallback methods */STDMETHODIMP HXFileSystemManager::RMAFSManagerCallback::Func(void){ m_Handle = 0; m_bIsCallbackPending = FALSE; if (m_pFSManager) { m_pFSManager->ProcessPendingRequest(); } return HXR_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -