hxfsmgr.cpp
上传用户:dangjiwu
上传日期:2013-07-19
资源大小:42019k
文件大小:25k
源码类别:

Symbian

开发平台:

Visual C++

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