hxfsmgr.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:24k
源码类别:

Symbian

开发平台:

C/C++

  1. /* ***** BEGIN LICENSE BLOCK ***** 
  2.  * Version: RCSL 1.0/RPSL 1.0 
  3.  *  
  4.  * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
  5.  *      
  6.  * The contents of this file, and the files included with this file, are 
  7.  * subject to the current version of the RealNetworks Public Source License 
  8.  * Version 1.0 (the "RPSL") available at 
  9.  * http://www.helixcommunity.org/content/rpsl unless you have licensed 
  10.  * the file under the RealNetworks Community Source License Version 1.0 
  11.  * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
  12.  * in which case the RCSL will apply. You may also obtain the license terms 
  13.  * directly from RealNetworks.  You may not use this file except in 
  14.  * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
  15.  * applicable to this file, the RCSL.  Please see the applicable RPSL or 
  16.  * RCSL for the rights, obligations and limitations governing use of the 
  17.  * contents of the file.  
  18.  *  
  19.  * This file is part of the Helix DNA Technology. RealNetworks is the 
  20.  * developer of the Original Code and owns the copyrights in the portions 
  21.  * it created. 
  22.  *  
  23.  * This file, and the files included with this file, is distributed and made 
  24.  * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  25.  * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  26.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
  27.  * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  28.  * 
  29.  * Technology Compatibility Kit Test Suite(s) Location: 
  30.  *    http://www.helixcommunity.org/content/tck 
  31.  * 
  32.  * Contributor(s): 
  33.  *  
  34.  * ***** END LICENSE BLOCK ***** */ 
  35. #include "hxtypes.h"
  36. #include "hxresult.h"
  37. #include "hxcom.h"
  38. #include "hxcomm.h"
  39. #include "hxchkpt.h"
  40. #include "hxfiles.h"
  41. #include "hxauth.h"
  42. #include "hxlist.h"
  43. #include "hxstrutl.h"
  44. #include "dbcs.h"
  45. #include "hxplugn.h"
  46. #include "plghand2.h"
  47. #include "hxrquest.h"
  48. #include "hxplugn.h"
  49. #include "hxfsmgr.h"
  50. #include "hxmon.h"
  51. #include "chxpckts.h"
  52. #include "plghand2.h"
  53. //#include "hxperf.h"
  54. #ifdef _MACINTOSH
  55. #include "hx_moreprocesses.h"
  56. #endif
  57. #include "hxheap.h"
  58. #ifdef _DEBUG
  59. #undef HX_THIS_FILE
  60. static const char HX_THIS_FILE[] = __FILE__;
  61. #endif
  62. #if !defined(HELIX_CONFIG_NOSTATICS)
  63. BOOL HXFileSystemManager::zm_IsInited = FALSE;
  64. CHXMapStringToOb    HXFileSystemManager::zm_ShortNameMap;
  65. CHXMapStringToOb    HXFileSystemManager::zm_ProtocolMap;
  66. CHXSimpleList     HXFileSystemManager::zm_CacheList;
  67. #else
  68. #include "globals/hxglobals.h"
  69. const BOOL HXFileSystemManager::zm_IsInited = FALSE;
  70. const CHXMapStringToOb* const HXFileSystemManager::zm_ShortNameMap = NULL;
  71. const CHXMapStringToOb* const HXFileSystemManager::zm_ProtocolMap = NULL;
  72. const CHXSimpleList* const HXFileSystemManager::zm_CacheList = NULL;
  73. #endif
  74. HXFileSystemManager::HXFileSystemManager(IUnknown* pContext)
  75.     : m_lRefCount(0)
  76.     , m_pContext(pContext)
  77.     , m_pSamePool(0)
  78.     , m_pFSManagerResponse(0)
  79.     , m_pRequest(NULL)
  80.     , m_pCallback(NULL)
  81.     , m_pScheduler(NULL)
  82.     , m_pOriginalObject(NULL)
  83.     , m_pRelativePath(NULL)
  84. {
  85.     if (m_pContext)
  86.     {
  87. m_pContext->AddRef();
  88. InitMountPoints(m_pContext);
  89.     }
  90. }
  91. void HXFileSystemManager::InitMountPoints(IUnknown* pContext)
  92. {
  93.     static const char* const  PH_BASE_STR  = "FSMount.";
  94.     static const UINT32  PH_BASE_LEN = 8;
  95.     static const char* const  PH_ELEM_STR = "elem";
  96.     static const UINT32  PH_ELEM_LEN  = 4;
  97.     static const UINT32  PH_MAX_INT32_AS_STRING_LEN = 20;
  98.     static const UINT32  PH_MAX_MEMBER_LEN  = 20;
  99. #if defined(HELIX_CONFIG_NOSTATICS)
  100.     BOOL& zm_IsInited =
  101. (BOOL&)HXGlobalInt32::Get(&HXFileSystemManager::zm_IsInited);
  102. #endif
  103.     if (zm_IsInited)
  104. return;
  105.     zm_IsInited = TRUE;
  106.     IHXBuffer* mount_point = 0;
  107.     IHXBuffer* real_short_name = 0;
  108.     const char* short_name = 0;
  109.     IHXValues* options = 0;
  110.     IHXRegistry* pRegistry;
  111.     IHXValues* pNameList;
  112.     if(HXR_OK != pContext->QueryInterface(IID_IHXRegistry,
  113.     (void**)&pRegistry))
  114.     {
  115. return;
  116.     }
  117.     if(HXR_OK != pRegistry->GetPropListByName("config.FSMount", pNameList))
  118.     {
  119. pRegistry->Release();
  120. return;
  121.     }
  122.     HX_RESULT res;
  123.     const char* plugName;
  124.     UINT32 plug_id;
  125.     res = pNameList->GetFirstPropertyULONG32(plugName, plug_id);
  126.     while(res == HXR_OK)
  127.     {
  128. HXPropType plugtype = pRegistry->GetTypeById(plug_id);
  129. if(plugtype != PT_COMPOSITE)
  130.     res = HXR_FAIL;
  131. else
  132. {
  133.     short_name = strrchr(plugName, '.');
  134.     if(!short_name)
  135. short_name = plugName;
  136.     else
  137. short_name++;
  138.     IHXValues* pPropList;
  139.     if(HXR_OK == pRegistry->GetPropListById(plug_id, pPropList))
  140.     {
  141. const char* propName;
  142. UINT32 prop_id;
  143. options = new CHXHeader();
  144. options->AddRef();
  145. res = pPropList->GetFirstPropertyULONG32(propName, prop_id);
  146. while(res == HXR_OK)
  147. {
  148.     HXPropType type = pRegistry->GetTypeById(prop_id);
  149.     const char*propSubName = strrchr(propName, '.') + 1;
  150.     switch(type)
  151.     {
  152. case PT_INTEGER:
  153. {
  154.     INT32 val;
  155.     if(HXR_OK == pRegistry->GetIntById(prop_id, val))
  156.     {
  157. options->SetPropertyULONG32(propSubName, val);
  158.     }
  159.     break;
  160. }
  161. case PT_STRING:
  162. {
  163.     IHXBuffer* pBuffer;
  164.     if(HXR_OK == pRegistry->GetStrById(prop_id,
  165.        pBuffer))
  166.     {
  167. options->SetPropertyBuffer(propSubName,
  168.     pBuffer);
  169. pBuffer->Release();
  170.     }
  171.     break;
  172. }
  173. case PT_BUFFER:
  174. {
  175.     IHXBuffer* pBuffer;
  176.     if(HXR_OK == pRegistry->GetBufById(prop_id,
  177.        pBuffer))
  178.     {
  179. options->SetPropertyBuffer(propSubName,
  180.    pBuffer);
  181. pBuffer->Release();
  182.     }
  183.     break;
  184. }
  185. default:
  186.     break;
  187.     }
  188.     res = pPropList->GetNextPropertyULONG32(propName, prop_id);
  189. }
  190. res = HXR_OK;
  191.     }
  192.     
  193.     if(HXR_OK == options->GetPropertyBuffer("MountPoint",
  194.      mount_point))
  195.     {
  196. if(HXR_OK == options->GetPropertyBuffer("ShortName",
  197. real_short_name))
  198.     short_name = (const char*) real_short_name->GetBuffer();
  199. AddMountPoint(short_name,(const char*)mount_point->GetBuffer(),
  200.   options, pContext);
  201. if(real_short_name)
  202. {
  203.     real_short_name->Release();
  204.     real_short_name = 0;
  205. }
  206. mount_point->Release();
  207.     }
  208.     res = pNameList->GetNextPropertyULONG32(plugName, plug_id);
  209. }
  210.     }
  211.     pNameList->Release();
  212.     pRegistry->Release();
  213. }
  214. HX_RESULT 
  215. HXFileSystemManager::AddMountPoint(const char* pszShortName,
  216.  const char* pszMountPoint,
  217.  IHXValues* pOptions,
  218.  IUnknown* pContext)
  219. {
  220. #if defined(HELIX_CONFIG_NOSTATICS)
  221.     CHXSimpleList& zm_CacheList =
  222. HXGlobalList::Get(&HXFileSystemManager::zm_CacheList);
  223.     CHXMapStringToOb& zm_ShortNameMap =
  224. HXGlobalMapStringToOb::Get(&HXFileSystemManager::zm_ShortNameMap);
  225.     CHXMapStringToOb& zm_ProtocolMap =
  226. HXGlobalMapStringToOb::Get(&HXFileSystemManager::zm_ProtocolMap);
  227. #endif
  228.     HX_RESULT     result     = HXR_OK;
  229.     IHXPlugin2Handler*     pPlugin2Handler = NULL;
  230.     CCacheInstance*     pCCacheInstance = NULL;
  231.     if (HXR_OK != pContext->QueryInterface(IID_IHXPlugin2Handler, (void**) &pPlugin2Handler))
  232. return HXR_FAIL;
  233.     if (!pszShortName)
  234.     {
  235. result = HXR_FAIL;
  236. goto cleanup;
  237.     }
  238.     
  239.     UINT32 nIndex; 
  240.     if (HXR_OK != pPlugin2Handler->FindIndexUsingStrings(PLUGIN_FILESYSTEMSHORT, 
  241.     (char*)pszShortName, NULL, NULL, NULL, NULL, nIndex))
  242.     {
  243. result = HXR_FAIL;
  244. goto cleanup;
  245.     }
  246.     IHXValues* pValues;
  247.     IHXBuffer* pProtocol;
  248.     pPlugin2Handler->GetPluginInfo(nIndex, pValues);
  249.     pValues->GetPropertyCString(PLUGIN_FILESYSTEMPROTOCOL, pProtocol);
  250.     char*   pszProtocol;
  251.     pszProtocol = (char*)pProtocol->GetBuffer();
  252.     pCCacheInstance     = new CCacheInstance;
  253.     pCCacheInstance->m_mount_point  = pszMountPoint;
  254.     pCCacheInstance->m_szProtocol   = pszProtocol;
  255.     pCCacheInstance->m_szShortName  = pszShortName;
  256.     pCCacheInstance->m_pOptions     = pOptions;
  257.     zm_ShortNameMap.SetAt(pszMountPoint, pCCacheInstance);
  258.     zm_ProtocolMap.SetAt(pszMountPoint, pCCacheInstance);
  259.     zm_CacheList.AddTail((void*)pCCacheInstance);
  260. cleanup:
  261.     return result;
  262. }
  263. IHXValues* HXFileSystemManager::GetOptionsGivenURL(const char* pURL)
  264. {
  265.     const char* pszFilePath = HXFindChar(pURL,':');
  266.     if (pszFilePath == 0)
  267.     {
  268. pszFilePath = pURL;
  269.     }
  270.     else
  271.     {
  272. pszFilePath++;
  273.     }
  274.     /*
  275.      * Must check all plugins, we cannot take just the first one who's mount point is the start
  276.      * of the url.  We must find the one who matches with the mount point of the greatest length.
  277.      * If p1 = /test and p2 = /test/test2 and the url is /test/test2/file we must use p2.
  278.      */
  279. #if defined(HELIX_CONFIG_NOSTATICS)
  280.     CHXSimpleList& zm_CacheList =
  281. HXGlobalList::Get(&HXFileSystemManager::zm_CacheList);
  282. #endif
  283.     
  284.     ULONG32     mount_point_len = 0;
  285.     CCacheInstance* pBestOptions = NULL;
  286.     for(CHXSimpleList::Iterator i = zm_CacheList.Begin(); i != zm_CacheList.End(); ++i)
  287.     {
  288. CCacheInstance* pCacheOptions = (CCacheInstance*) *i;
  289. if (pCacheOptions->m_mount_point.GetLength() > 0 &&
  290.     (strncmp(pCacheOptions->m_mount_point, pszFilePath, pCacheOptions->m_mount_point.GetLength()) == 0))
  291. {
  292.     if((UINT32)pCacheOptions->m_mount_point.GetLength() >= mount_point_len)
  293.     {
  294. mount_point_len = pCacheOptions->m_mount_point.GetLength();
  295. pBestOptions = pCacheOptions;
  296.     }
  297. }
  298.     }
  299.     if (pBestOptions)
  300.     {
  301. return pBestOptions->m_pOptions;
  302.     }
  303.     return NULL;
  304. }
  305. HXFileSystemManager::~HXFileSystemManager()
  306. {
  307.     if (m_pContext)
  308.     {
  309. m_pContext->Release();
  310. m_pContext = 0;
  311.     }
  312.     if(m_pSamePool)
  313.     {
  314. m_pSamePool->Release();
  315. m_pSamePool = NULL;
  316.     }
  317.     if (m_pFSManagerResponse)
  318.     {
  319. m_pFSManagerResponse->Release();
  320. m_pFSManagerResponse = 0;
  321.     }
  322.     HX_RELEASE(m_pRequest);
  323.     if (m_pCallback &&
  324. m_pCallback->m_bIsCallbackPending &&
  325. m_pScheduler)
  326.     {
  327. m_pScheduler->Remove(m_pCallback->m_Handle);
  328.     }
  329.     HX_RELEASE(m_pCallback);
  330.     HX_RELEASE(m_pScheduler);
  331.     HX_RELEASE(m_pOriginalObject);
  332.     HX_VECTOR_DELETE(m_pRelativePath);
  333. }
  334. // *** IUnknown methods ***
  335. /////////////////////////////////////////////////////////////////////////
  336. //  Method:
  337. // IUnknown::QueryInterface
  338. //  Purpose:
  339. // Implement this to export the interfaces supported by your 
  340. // object.
  341. //
  342. STDMETHODIMP HXFileSystemManager::QueryInterface(REFIID riid, void** ppvObj)
  343. {
  344.     QInterfaceList qiList[] =
  345.         {
  346.             { GET_IIDHANDLE(IID_IHXFileSystemManager), (IHXFileSystemManager*)this },
  347.             { GET_IIDHANDLE(IID_IUnknown), (IUnknown*)(IHXFileSystemManager*)this },
  348.         };
  349.     
  350.     return ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
  351. }
  352. /////////////////////////////////////////////////////////////////////////
  353. //  Method:
  354. // IUnknown::AddRef
  355. //  Purpose:
  356. // Everyone usually implements this the same... feel free to use
  357. // this implementation.
  358. //
  359. STDMETHODIMP_(ULONG32) HXFileSystemManager::AddRef()
  360. {
  361.     return InterlockedIncrement(&m_lRefCount);
  362. }
  363. /////////////////////////////////////////////////////////////////////////
  364. //  Method:
  365. // IUnknown::Release
  366. //  Purpose:
  367. // Everyone usually implements this the same... feel free to use
  368. // this implementation.
  369. //
  370. STDMETHODIMP_(ULONG32) HXFileSystemManager::Release()
  371. {
  372.     if (InterlockedDecrement(&m_lRefCount) > 0)
  373.     {
  374.         return m_lRefCount;
  375.     }
  376.     delete this;
  377.     return 0;
  378. }
  379. /*
  380.  * IHXFileSystemManager methods
  381.  */
  382. /************************************************************************
  383.  * Method:
  384.  *     IHXFileSystemManager::Init
  385.  * Purpose:
  386.  */
  387. STDMETHODIMP 
  388. HXFileSystemManager::Init 
  389.     (
  390.     IHXFileSystemManagerResponse* /*IN*/  pFileManagerResponse
  391.     )
  392. {
  393.     if (!pFileManagerResponse)
  394.     {
  395. return HXR_FAIL;
  396.     }
  397.     /* Release any earlier response */
  398.     if (m_pFSManagerResponse)
  399.     {
  400. m_pFSManagerResponse->Release();
  401. m_pFSManagerResponse = 0;
  402.     }
  403.     m_pFSManagerResponse = pFileManagerResponse;
  404.     m_pFSManagerResponse->AddRef();
  405.     /* 
  406.      * We might get released (and deleted) in the response object. so 
  407.      * Addref here and Release after the response function is called
  408.      */
  409.     AddRef();
  410.     
  411.     m_pFSManagerResponse->InitDone(HXR_OK);
  412.     /* Release for extra Addref */
  413.     Release();
  414.     return HXR_OK;
  415. }
  416. STDMETHODIMP
  417. HXFileSystemManager::GetFileObject(IHXRequest* pRequest,
  418.     IHXAuthenticator* pAuthenticator)
  419. {
  420.     HX_LOG_BLOCK( "HXFileSystemManager::GetFileObject" );
  421.     
  422.     HX_RESULT     theErr = HXR_OK;
  423.     HX_RELEASE(m_pRequest);
  424.     m_pRequest = pRequest;
  425.     if (m_pRequest)
  426.     {
  427. m_pRequest->AddRef();
  428.     }
  429.     m_State = e_GetFileObjectPending;
  430. #ifdef _MACINTOSH
  431.     if (!IsMacInCooperativeThread())
  432.     {
  433. if (!m_pScheduler)
  434. {
  435.     HX_VERIFY(m_pContext->QueryInterface(IID_IHXScheduler, (void**) &m_pScheduler) == HXR_OK);
  436. }
  437. if (!m_pCallback)
  438. {
  439.     m_pCallback = new RMAFSManagerCallback(this);
  440.     m_pCallback->AddRef();
  441. }
  442. HX_ASSERT(m_pCallback->m_bIsCallbackPending == FALSE);
  443. if (!m_pCallback->m_bIsCallbackPending)
  444. {
  445.     m_pCallback->m_bIsCallbackPending = TRUE;
  446.     m_pCallback->m_Handle = m_pScheduler->RelativeEnter(m_pCallback, 0);
  447. }
  448.         return HXR_OK;
  449.     }
  450. #endif
  451.     return (ProcessGetFileObjectPending());
  452. }
  453. HX_RESULT
  454. HXFileSystemManager::ProcessGetFileObjectPending()
  455. {
  456.     HX_LOG_BLOCK( "HXFileSystemManager::ProcessGetFileObjectPending" );
  457.     HX_RESULT theErr = HXR_OK;
  458.     IUnknown*     pUnknownFS = NULL;
  459.     IUnknown*     pUnknownFileObject = NULL;
  460.     IHXFileSystemObject*   pFileSystem = NULL;
  461.     IHXRequestHandler*     pRequestHandler = NULL;
  462.     IHXPlugin2Handler*     pPlugin2Handler = NULL; 
  463.     if (!m_pContext)
  464.     {
  465. return HXR_FAILED;
  466.     }
  467.     /* 
  468.      * We might get released (and deleted) in the response object. so 
  469.      * Addref here and Release after the response function is called
  470.      */
  471.     AddRef();
  472.     
  473.     // get the plugin handler 
  474.     if (HXR_OK != m_pContext->QueryInterface(IID_IHXPlugin2Handler, (void**)&pPlugin2Handler))
  475.     {
  476.         theErr = HXR_FAILED;
  477. goto exit;
  478.     }
  479.     const char* pURL;
  480.     HX_ASSERT( NULL != m_pRequest );
  481.     if ( ( NULL == m_pRequest ) || ( m_pRequest->GetURL(pURL) != HXR_OK ) )
  482.     {
  483.         theErr = HXR_FAILED;
  484. goto exit;
  485.     }
  486.     const char* pProtocolEnd;
  487.     pProtocolEnd = HXFindChar(pURL,':');
  488.     if (!pProtocolEnd)
  489.     {
  490.         theErr = HXR_FAILED;
  491.     }
  492.     if (!theErr)
  493.     {
  494. int nLength = pProtocolEnd - pURL;
  495. CHXString strProtocol(pURL,nLength);
  496. if (HXR_OK != (theErr = pPlugin2Handler->FindPluginUsingStrings(PLUGIN_CLASS, PLUGIN_FILESYSTEM_TYPE, 
  497.     PLUGIN_FILESYSTEMPROTOCOL, (char*)(const char*)strProtocol, NULL, NULL, pUnknownFS)))
  498. {
  499.     goto exit;
  500. }
  501. IHXPlugin* pPluginInterface = NULL;
  502. if(!theErr)
  503. {
  504.     theErr = pUnknownFS->QueryInterface(IID_IHXPlugin,
  505. (void**)&pPluginInterface);
  506. }
  507. if(!theErr)
  508. {
  509.     theErr = pPluginInterface->InitPlugin(m_pContext);
  510.     pPluginInterface->Release();
  511. }
  512. if(!theErr)
  513. {
  514.     theErr = pUnknownFS->QueryInterface(IID_IHXFileSystemObject,
  515. (void**)&pFileSystem);
  516. }
  517. // At this point we should initalize the file system.to do this we must find the 
  518. // IHXValues for this mount path in the Options Cache.
  519. IHXValues* pOptions = NULL;
  520. pOptions = GetOptionsGivenURL(pURL);
  521. pFileSystem->InitFileSystem(pOptions);
  522. HX_RELEASE(pOptions);
  523. if(!theErr)
  524. {
  525.     theErr = pFileSystem->CreateFile(&pUnknownFileObject);
  526. }
  527. if(!theErr)
  528. {
  529.     if(HXR_OK == pUnknownFileObject->QueryInterface(
  530. IID_IHXRequestHandler,
  531. (void**)&pRequestHandler))
  532.     {
  533. pRequestHandler->SetRequest(m_pRequest);
  534.     }
  535.     else
  536.     {
  537. theErr = HXR_FAILED;
  538.     }
  539. }
  540.     }
  541.     else
  542.     {
  543. theErr = HXR_FAILED;
  544.     }
  545.     if (!theErr && pUnknownFileObject)
  546.     {
  547. m_pFSManagerResponse->FileObjectReady(HXR_OK, pUnknownFileObject);
  548.     }
  549.     else
  550.     {
  551. m_pFSManagerResponse->FileObjectReady(HXR_FAILED, NULL);
  552.     }
  553. exit:
  554.     HX_RELEASE(pUnknownFS);
  555.     HX_RELEASE(pUnknownFileObject);
  556.     HX_RELEASE(pRequestHandler);
  557.     HX_RELEASE(pFileSystem);
  558.     HX_RELEASE(pPlugin2Handler);
  559. #ifndef _MACINTOSH
  560.     // Note: This change is necessary for the Macintosh build due to the fact
  561.     // that this platform uses a different approach in GetFileObject.  The problem
  562.     // is that file object processing had generally been done recursively, with
  563.     // GetFileObject calling ProcessGetFileObjectPending, which in turn indirectly
  564.     // invoked GetFileObject in a pattern of mutual recursion.  The recursion had
  565.     // always ended with a call to ProcessGetFileObjectPending.  With the change
  566.     // in GetFileObject:
  567.     //     #ifdef _MACINTOSH
  568.     //      if (!IsMacInCooperativeThread())
  569.     // the recursion would terminate in a GetFileObject call.  This call would
  570.     // unwind to the scheduler, which would then process the queued file object
  571.     // by calling ProcessGetFileObjectPending.  However, since the request object
  572.     // was freed during the unwinding of the recursion, this object was no longer
  573.     // available and hence the process failed.
  574.     //
  575.     // The best short term fix appears to be to remove this release.  The best long
  576.     // term fix is to eliminate the recursion (which would also simplify maintenance). 
  577.     //     -cconover  XXX
  578.     
  579.     HX_RELEASE(m_pRequest);
  580. #endif
  581.     /* 
  582.      * Release for extra Addref
  583.      */
  584.     Release();
  585.     return theErr;
  586. }
  587. /*
  588.  * In this implementation of FSManager, GetNewFileObject is wholly
  589.  * equivalent to GetFileObject.  GetNewFileObject exists for the
  590.  * server's FSManager since it would otherwise be impossible to get
  591.  * a brand new file object for writing, as the DoesExist checks
  592.  * would fail for every file system checked.  This implementation has
  593.  * ambiguities between URL's and file systems, so there is no
  594.  * different functionality needed.
  595.  */
  596. STDMETHODIMP
  597. HXFileSystemManager::GetNewFileObject(IHXRequest* pRequest,
  598.        IHXAuthenticator* pAuthenticator)
  599. {
  600.     return GetFileObject(pRequest, pAuthenticator);
  601. }
  602. STDMETHODIMP
  603. HXFileSystemManager::GetRelativeFileObject(IUnknown* pOriginalObject,
  604.  const char* pRelativePath)
  605. {
  606.     HX_RESULT     theErr = HXR_OK;
  607.     if(!pRelativePath)
  608.     {
  609. return HXR_FAIL;
  610.     }
  611.     HX_RELEASE(m_pOriginalObject);
  612.     m_pOriginalObject = pOriginalObject;
  613.     if (m_pOriginalObject)
  614.     {
  615. m_pOriginalObject->AddRef();
  616.     }
  617.     HX_VECTOR_DELETE(m_pRelativePath);
  618.     m_pRelativePath = new_string(pRelativePath);
  619.     m_State = e_GetRelativeFileObjectPending;
  620. #ifdef _MACINTOSH
  621.     if (!IsMacInCooperativeThread())
  622.     {
  623. if (!m_pScheduler)
  624. {
  625.     HX_VERIFY(m_pContext->QueryInterface(IID_IHXScheduler, (void**) &m_pScheduler) == HXR_OK);
  626. }
  627. if (!m_pCallback)
  628. {
  629.     m_pCallback = new RMAFSManagerCallback(this);
  630.     m_pCallback->AddRef();
  631. }
  632. HX_ASSERT(m_pCallback->m_bIsCallbackPending == FALSE);
  633. if (!m_pCallback->m_bIsCallbackPending)
  634. {
  635.     m_pCallback->m_bIsCallbackPending = TRUE;
  636.     m_pCallback->m_Handle = m_pScheduler->RelativeEnter(m_pCallback, 0);
  637. }
  638.         return HXR_OK;
  639.     }
  640. #endif
  641.     return (ProcessGetRelativeFileObjectPending());
  642. }
  643. HX_RESULT
  644. HXFileSystemManager::ProcessGetRelativeFileObjectPending()
  645. {
  646.     HX_RESULT theErr = HXR_OK;
  647.     IHXRequestHandler* pRequestHandlerOrigional = NULL;
  648.     IHXRequest* pRequestOld = NULL;
  649.     AddRef();
  650.     
  651.     if (!m_pOriginalObject)
  652.      goto exit;
  653.     if(HXR_OK != m_pOriginalObject->QueryInterface(IID_IHXGetFileFromSamePool,
  654.        (void**)&m_pSamePool))
  655.     {
  656. theErr = HXR_FAIL;
  657. goto exit;
  658.     }
  659.     if 
  660.     (
  661. HXR_OK != m_pOriginalObject->QueryInterface
  662. (
  663.     IID_IHXRequestHandler,
  664.     (void**)&pRequestHandlerOrigional
  665. )
  666. ||
  667. !pRequestHandlerOrigional
  668. ||
  669. HXR_OK != pRequestHandlerOrigional->GetRequest(pRequestOld)
  670. ||
  671. !pRequestOld
  672.     )
  673.     {
  674. HX_RELEASE(pRequestHandlerOrigional);
  675. HX_RELEASE(pRequestOld);
  676. theErr = HXR_FAIL;
  677. goto exit;
  678.     }
  679.     HX_RELEASE(pRequestHandlerOrigional);
  680.     /*
  681.      * Create an IHXRequest object for the new file
  682.      */
  683.     HX_RELEASE(m_pRequest);
  684.     CHXRequest::CreateFrom(pRequestOld, &m_pRequest);
  685.     HX_RELEASE(pRequestOld);
  686.     m_pRequest->SetURL(m_pRelativePath);
  687.     if(HXR_OK != m_pSamePool->GetFileObjectFromPool(this))
  688.     {
  689. theErr = HXR_FAIL;
  690. goto exit;
  691.     }
  692. exit:
  693.     HX_RELEASE(m_pSamePool);
  694.     HX_RELEASE(m_pOriginalObject);
  695.     HX_VECTOR_DELETE(m_pRelativePath);
  696.     Release();
  697.     return theErr;
  698. }
  699. STDMETHODIMP
  700. HXFileSystemManager::FileObjectReady(HX_RESULT status, IUnknown* pUnknown)
  701. {
  702.     IHXRequestHandler* pRequestHandler = NULL;
  703.     if(HXR_OK == status)
  704.     {
  705. if(HXR_OK == pUnknown->QueryInterface(IID_IHXRequestHandler,
  706.     (void**)&pRequestHandler))
  707. {
  708.     pRequestHandler->SetRequest(m_pRequest);
  709. }
  710. else
  711. {
  712.     pUnknown = 0;
  713.     status = HXR_FAILED;
  714. }
  715. pRequestHandler->Release();
  716.     }
  717.     HX_RELEASE(m_pRequest);
  718.     /* 
  719.      * We might get released (and deleted) in the response object. so 
  720.      * Addref here and Release after the response function is called
  721.      */
  722.     AddRef();
  723.     
  724.     if (m_pFSManagerResponse)
  725.     {
  726. m_pFSManagerResponse->FileObjectReady(status, pUnknown);
  727.     }
  728.     /* 
  729.      * Release for extra Addref
  730.      */
  731.     Release();
  732.     return HXR_OK;
  733. }
  734. STDMETHODIMP 
  735. HXFileSystemManager::GetDirObjectFromURL(const char* pURL)
  736. {
  737.     return HXR_NOTIMPL;
  738. }
  739. void
  740. HXFileSystemManager::ProcessPendingRequest()
  741. {
  742.     switch(m_State)
  743.     {
  744. case e_GetFileObjectPending:
  745.     ProcessGetFileObjectPending();
  746.     break;
  747. case e_GetRelativeFileObjectPending:
  748.     ProcessGetRelativeFileObjectPending();
  749.     break;
  750. default:
  751.     HX_ASSERT(FALSE);
  752.     break;
  753.     }    
  754. }
  755. // HXFileSystemManager::RMAFSManagerCallback
  756. HXFileSystemManager::RMAFSManagerCallback::RMAFSManagerCallback(HXFileSystemManager* pFSManager) :
  757.      m_lRefCount (0)
  758.     ,m_pFSManager (pFSManager)
  759.     ,m_Handle (0)
  760.     ,m_bIsCallbackPending(FALSE)
  761. {
  762. }
  763. HXFileSystemManager::RMAFSManagerCallback::~RMAFSManagerCallback()
  764. {
  765. }
  766. /*
  767.  * IUnknown methods
  768.  */
  769. /////////////////////////////////////////////////////////////////////////
  770. // Method:
  771. // IUnknown::QueryInterface
  772. // Purpose:
  773. // Implement this to export the interfaces supported by your 
  774. // object.
  775. //
  776. STDMETHODIMP HXFileSystemManager::RMAFSManagerCallback::QueryInterface(REFIID riid, void** ppvObj)
  777. {
  778.     QInterfaceList qiList[] =
  779.         {
  780.             { GET_IIDHANDLE(IID_IHXCallback), (IHXCallback*)this },
  781.             { GET_IIDHANDLE(IID_IUnknown), (IUnknown*)(IHXCallback*)this },
  782.         };
  783.     
  784.     return ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
  785. }
  786. /////////////////////////////////////////////////////////////////////////
  787. // Method:
  788. // IUnknown::AddRef
  789. // Purpose:
  790. // Everyone usually implements this the same... feel free to use
  791. // this implementation.
  792. //
  793. STDMETHODIMP_(ULONG32) HXFileSystemManager::RMAFSManagerCallback::AddRef()
  794. {
  795.     return InterlockedIncrement(&m_lRefCount);
  796. }
  797. /////////////////////////////////////////////////////////////////////////
  798. // Method:
  799. // IUnknown::Release
  800. // Purpose:
  801. // Everyone usually implements this the same... feel free to use
  802. // this implementation.
  803. //
  804. STDMETHODIMP_(ULONG32) HXFileSystemManager::RMAFSManagerCallback::Release()
  805. {
  806.     if (InterlockedDecrement(&m_lRefCount) > 0)
  807.     {
  808. return m_lRefCount;
  809.     }
  810.     delete this;
  811.     return 0;
  812. }
  813. /*
  814.  * UDPSchedulerCallback methods
  815.  */
  816. STDMETHODIMP HXFileSystemManager::RMAFSManagerCallback::Func(void)
  817. {
  818.     m_Handle = 0;
  819.     m_bIsCallbackPending = FALSE;
  820.     if (m_pFSManager)
  821.     {
  822. m_pFSManager->ProcessPendingRequest();
  823.     }
  824.     return HXR_OK;
  825. }