📄 smplfsys.cpp
字号:
BOOL bLog = FALSE;
/*
* XXX PM this is weak. I need a way to show these options
* but only if explicitly asked to do so. Ideally we would
* use the IRMErrorMessages with HXLOG_DEBUG and --sdm for
* server but I can't here because no context gets passed
* to file system object until its first connection.
* Can you believe that?
*/
m_options->GetPropertyULONG32("LogOptionalParams",
ulTemp);
bLog = ulTemp ? TRUE : FALSE;
ulTemp = 0;
m_options->GetPropertyULONG32("DisableMemoryMappedIO",
ulTemp);
m_bDisableMemoryMappedIO = ulTemp ? TRUE : FALSE;
ulTemp = 0;
m_options->GetPropertyULONG32("EnableFileLocking",
ulTemp);
m_bEnableFileLocking = ulTemp ? TRUE : FALSE;
ulTemp = 0;
m_options->GetPropertyULONG32("MaxIterationLevel", ulTemp);
if (ulTemp)
{
m_ulMaxIterationLevel = ulTemp;
}
if (bLog)
{
char pNumericMount[50]; /* Flawfinder: ignore */
IHXBuffer* pBuffer = 0;
const char* pMount;
m_options->GetPropertyCString("MountPoint", pBuffer);
if (!pBuffer)
{
m_options->GetPropertyBuffer("MountPoint", pBuffer);
if (!pBuffer)
{
m_options->GetPropertyULONG32("MountPount", ulTemp);
}
}
if (pBuffer)
{
pMount = (const char*)pBuffer->GetBuffer();
}
else
{
pMount = pNumericMount;
sprintf(pNumericMount, "%lu", ulTemp); /* Flawfinder: ignore */
}
printf("Optional smplfsys (pn-local) parameters for"
" MountPoint: %s\n", pMount);
HX_RELEASE(pBuffer);
printf("DisableMemoryMappedIO: %s\n",
m_bDisableMemoryMappedIO ? "TRUE" : "FALSE");
printf("EnableFileLocking: %s\n",
m_bEnableFileLocking ? "TRUE" : "FALSE");
printf("MaxIterationLevel: %lu\n",
m_ulMaxIterationLevel);
ulTemp = 0;
m_options->GetPropertyULONG32("MMapChunkSize", ulTemp);
if (ulTemp)
{
printf("MMapChunkSize: %lu\n", ulTemp);
}
}
}
if (base_path_buf)
{
base_path_buf->Release();
}
return HXR_OK;
}
/////////////////////////////////////////////////////////////////////////
// Method:
// IHXFileSystemObject::CreateFile
// Purpose:
// TBD
//
STDMETHODIMP CSimpleFileSystem::CreateFile
(
IUnknown** /*OUT*/ ppFileObject
)
{
HX_LOG_BLOCK( "CSimpleFileSystem::CreateFile" );
CSimpleFileObject* pFileObj =
new CSimpleFileObject(m_base_path,
this,
m_pContext,
m_ulMaxIterationLevel);
if (pFileObj)
{
if (HXR_OK == pFileObj->QueryInterface(IID_IUnknown,
(void**)ppFileObject))
{
return HXR_OK;
}
return HXR_UNEXPECTED;
}
return HXR_OUTOFMEMORY;
}
/////////////////////////////////////////////////////////////////////////
// Method:
// CSimpleFileSystem::CreateDir
// Purpose:
// TBD
//
STDMETHODIMP CSimpleFileSystem::CreateDir
(
IUnknown** /*OUT*/ ppDirObject
)
{
return HXR_NOTIMPL;
}
CSimpleFileObject::CSimpleFileObject(CHXString& base_path,
CSimpleFileSystem *pFS,
IUnknown* pContext,
UINT32 ulMaxIterationLevel)
: m_lRefCount(0)
, m_ulFlags(0)
, m_bLocalClose(FALSE)
, m_pContext(pContext)
, m_pCommonClassFactory(NULL)
, m_pFileResponse(NULL)
, m_pFileSystem(pFS)
, m_pFilename(NULL)
, m_pRequest(0)
, m_pDescriptorReg(0)
, m_pDirResponse(NULL)
, m_pDirList(NULL)
, m_pScheduler(NULL)
, m_pStackCallback(NULL)
, m_bInRead(FALSE)
, m_bReadPending(FALSE)
, m_bAsyncReadPending(FALSE)
, m_ulPendingReadCount(0)
, m_ulSize(0)
, m_ulPos(0)
, m_bAsyncAccess(TRUE)
, m_bCanBeReOpened(0)
#ifdef _MACINTOSH
, m_pDataFile(NULL)
, m_pAsyncFileResponse(NULL)
, m_pInterruptState(NULL)
, m_pFileStatResponse(NULL)
, m_eSeekReason(EXTERNAL_SEEK)
, m_ulPreSeekPosition(0)
, m_bFileToBeClosed(FALSE)
#endif
, m_nFd(-1)
, m_ulMaxIterationLevel(ulMaxIterationLevel)
, m_pUnknownUserContext(NULL)
, m_ulPendingSeekOffset(0)
, m_usPendingSeekWhence(SEEK_SET)
#if defined(HELIX_FEATURE_PROGDOWN)
, m_pProgDownMon(NULL)
, m_ulCallbackState(CallbackStateUnknown)
, m_bProgDownEnabled(TRUE)
#endif /* #if defined(HELIX_FEATURE_PROGDOWN) */
{
MLOG_LEAK("CON CSimpleFileObject this=0x%08x\n", this);
#ifndef HELIX_CONFIG_NOSTATICS
smpl_nRefCount++;
#endif // HELIX_CONFIG_NOSTATICS
m_base_path = base_path;
if (m_pFileSystem)
{
m_pFileSystem->AddRef();
}
if (m_pContext)
{
m_pContext->AddRef();
#ifdef USE_THREADSAFE_SCHEDULER
m_pContext->QueryInterface(IID_IHXThreadSafeScheduler, (void**) &m_pScheduler);
if (!m_pScheduler)
{
m_pContext->QueryInterface(IID_IHXScheduler, (void**) &m_pScheduler);
}
#else
m_pContext->QueryInterface(IID_IHXScheduler, (void**) &m_pScheduler);
#endif //USE_THREADSAFE_SCHEDULER
#if !defined _MACINTOSH
IHXDataFileFactory* pDFFact = new HXDataFileFactory;;
pDFFact->AddRef();
{
DPRINTF(0x5d000000, ("CSFO::CSFO() -- after QI\n"));
{
pDFFact->CreateFile(m_pDataFile, m_pContext,
pFS->m_pCommonObj, pFS->m_bDisableMemoryMappedIO,
pFS->m_ulChunkSize, pFS->m_bEnableFileLocking,
TRUE); // Always prefer async I/O
if (!m_pDataFile)
{
#ifndef _WIN16
DPRINTF(0x5d000000, ("Internal Error s/546\n"));
#endif
pDFFact->Release();
return;
}
}
}
pDFFact->Release();
#endif /* !defined _MACINTOSH */
m_pContext->QueryInterface(IID_IHXCommonClassFactory,
(void **)&m_pCommonClassFactory);
}
m_pStackCallback = new CHXGenericCallback(this, CSimpleFileObject::StackCallback);
if (m_pStackCallback)
{
m_pStackCallback->AddRef();
}
#if defined (_MACINTOSH)
m_pAsyncFileResponse = new SMPLAsyncResponse(this);
if (m_pContext)
{
m_pContext->QueryInterface(IID_IHXInterruptState, (void**) &m_pInterruptState);
}
#endif
#if defined(HELIX_FEATURE_PROGDOWN)
m_pProgDownMon = new CProgressiveDownloadMonitor();
#endif /* #if defined(HELIX_FEATURE_PROGDOWN) */
};
CSimpleFileObject::~CSimpleFileObject()
{
MLOG_LEAK("DES CSimpleFileObject this=0x%08x\n", this);
#ifndef HELIX_CONFIG_NOSTATICS
smpl_nRefCount--;
#endif // HELIX_CONFIG_NOSTATICS
m_bLocalClose = TRUE;
Close();
};
// *** IUnknown methods ***
/////////////////////////////////////////////////////////////////////////
// Method:
// IUnknown::QueryInterface
// Purpose:
// Implement this to export the interfaces supported by your
// object.
//
STDMETHODIMP CSimpleFileObject::QueryInterface(REFIID riid, void** ppvObj)
{
QInterfaceList qiList[] =
{
{ GET_IIDHANDLE(IID_IUnknown), this },
{ GET_IIDHANDLE(IID_IHXFileObject), (IHXFileObject*) this },
{ GET_IIDHANDLE(IID_IHXDirHandler), (IHXDirHandler*) this },
{ GET_IIDHANDLE(IID_IHXFileStat), (IHXFileStat*) this },
{ GET_IIDHANDLE(IID_IHXFileExists), (IHXFileExists*) this },
{ GET_IIDHANDLE(IID_IHXGetFileFromSamePool), (IHXGetFileFromSamePool*) this },
{ GET_IIDHANDLE(IID_IHXRequestHandler), (IHXRequestHandler*) this },
{ GET_IIDHANDLE(IID_IHXFileRename), (IHXFileRename*) this },
{ GET_IIDHANDLE(IID_IHXFileRemove), (IHXFileRemove*) this },
{ GET_IIDHANDLE(IID_IHXFileMove), (IHXFileMove*) this },
{ GET_IIDHANDLE(IID_IHXThreadSafeMethods), (IHXThreadSafeMethods*) 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) CSimpleFileObject::AddRef()
{
return InterlockedIncrement(&m_lRefCount);
}
/////////////////////////////////////////////////////////////////////////
// Method:
// IUnknown::Release
// Purpose:
// Everyone usually implements this the same... feel free to use
// this implementation.
//
STDMETHODIMP_(ULONG32) CSimpleFileObject::Release()
{
if (InterlockedDecrement(&m_lRefCount) > 0)
{
return m_lRefCount;
}
delete this;
return 0;
}
/************************************************************************
* Method:
* IHXFileObject::Init
* Purpose:
* Associates a file object with the file response object it should
* notify of operation completness. This method should also check
* for validity of the object (for example by opening it if it is
* a local file).
*/
STDMETHODIMP
CSimpleFileObject::Init
(
ULONG32 /*IN*/ ulFlags,
IHXFileResponse* /*IN*/ pFileResponse
)
{
MLOG_GEN(NULL, "CSimpleFileObject::Init(0x%08x,0x%08x) this=0x%08x\n",
ulFlags, pFileResponse, this);
HX_LOG_BLOCK( "CSimpleFileObject::Init" );
DPRINTF(0x5d000000, ("CSFO::Init(flags(0x%x), pFileResponse(%p)) "
"-- fd(%d)\n", ulFlags, pFileResponse, m_nFd));
HX_RESULT lReturnVal = HXR_OK;
HX_RESULT resultInitDone = HXR_OK;
IHXRequestContext* pIHXRequestContextCurrent = NULL;
if (!pFileResponse) return HXR_INVALID_PARAMETER;
if (!m_pRequest) return HXR_INVALID_PARAMETER;
/* Release any previous reponses */
if (m_pFileResponse)
{
m_pFileResponse->Release();
}
m_pFileResponse = pFileResponse;
m_pFileResponse->AddRef();
/* have we already opened/created a file */
if (m_nFd != -1)
{
m_bReadPending = FALSE;
m_ulPendingReadCount = 0;
/* remove any pending callbacks */
if (m_pStackCallback) m_pStackCallback->Cancel(m_pScheduler);
/* if flags are same, then we are all set and there
* is no need to do anything further
*/
if (m_ulFlags == ulFlags || ulFlags == 0)
{
/* If we have already opened a file, then seek back
* to zero during re-initialization
*/
#ifndef _MACINTOSH
HX_RESULT result = m_pDataFile->Seek(0, SEEK_SET);
m_pFileResponse->InitDone(result);
return result;
#else
BOOL bAtInterrupt = FALSE;
if (m_pInterruptState)
{
bAtInterrupt = m_pInterruptState->AtInterruptTime();
}
/* I want to know if we ever reach here at interrupt time
* Please e-mail me a repro case if you hit this assert
* - RA
*/
HX_ASSERT(bAtInterrupt == FALSE);
m_eSeekReason = REINIT_SEEK;
HX_RESULT theResult = m_pDataFile->SafeSeek(0, SEEK_SET, bAtInterrupt);
if (theResult != HXR_OK)
{
m_pFileResponse->InitDone(HXR_FAIL);
}
return theResult;
#endif
/*
m_pFileResponse->InitDone(HXR_OK);
return HXR_OK;
*/
}
#ifdef _MACINTOSH
HX_RELEASE(m_pDataFile);
m_pDataFile = NULL;
#else
DPRINTF(0x5d000000, ("CSFO::Init() -- m_pDataFile->Close()\n"));
if (m_pDescriptorReg)
{
m_pDescriptorReg->UnRegisterDescriptors(1);
}
m_pDataFile->Close();
m_nFd = -1;
#endif
}
m_ulFlags = ulFlags;
if (!m_pCommonClassFactory)
{
m_pContext->QueryInterface(IID_IHXCommonClassFactory,
(void **)&m_pCommonClassFactory);
}
HX_RELEASE(m_pUnknownUserContext);
if (m_pRequest && SUCCEEDED(m_pRequest->QueryInterface(
IID_IHXRequestContext, (void**)&pIHXRequestContextCurrent)))
{
pIHXRequestContextCurrent->GetUserContext(m_pUnknownUserContext);
pIHXRequestContextCurrent->Release();
}
DPRINTF(0x5d000000, ("CSFO::Init() -- (2) _OpenFile()\n"));
lReturnVal = _OpenFile(ulFlags);
DPRINTF(0x5d000000, ("CSFO::Init(flags(0x%x), pFileResponse(%p)) "
"-- result(0x%x), m_nFd(%d)\n",
ulFlags, pFileResponse, lReturnVal, m_nFd));
if ((m_nFd == -1 || FAILED(lReturnVal)))
{
// XXXSSH -- probably obsolete
if (lReturnVal != HXR_NOT_AUTHORIZED)
{
lReturnVal = HXR_DOC_MISSING;
}
}
else
{
lReturnVal = HXR_OK;
}
#if defined(HELIX_FEATURE_PROGDOWN)
// If we are writing to the file, then disable
// the progressive download features
m_bProgDownEnabled = (m_ulFlags & HX_FILE_WRITE ? FALSE : TRUE);
if (m_pProgDownMon && m_bProgDownEnabled)
{
m_pProgDownMon->Init(m_pContext, m_pDataFile, this);
}
#endif /* #if defined(HELIX_FEATURE_PROGDOWN) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -