// ==++==
//
//
// Copyright (c) 2006 Microsoft Corporation. All rights reserved.
//
// The use and distribution terms for this software are contained in the file
// named license.txt, which can be found in the root of this distribution.
// By using this software in any fashion, you are agreeing to be bound by the
// terms of this license.
//
// You must not remove this notice, or any other, from this software.
//
//
// ==--==
//============================================================
//
// Class: COMIsolatedStorage
//
// Created By: Shajan Dasan
// Contact: Tarik Soulami
//
// Purpose: Native Implementation of IsolatedStorage
//
// Date: Feb 14, 2000
//
//============================================================
#include "common.h"
#include "excep.h"
#include "eeconfig.h"
#include "comstring.h"
#include "comstringcommon.h" // RETURN() macro
#include "comisolatedstorage.h"
#define IS_ROAMING(x) ((x) & ISS_ROAMING_STORE)
void COMIsolatedStorage::ThrowISS(HRESULT hr)
{
CONTRACTL {
THROWS;
GC_TRIGGERS;
MODE_COOPERATIVE;
} CONTRACTL_END;
static MethodTable * pMT = NULL;
if (pMT == NULL)
pMT = g_Mscorlib.GetClass(CLASS__ISSEXCEPTION);
_ASSERTE(pMT && "Unable to load the throwable class !");
if ((hr >= ISS_E_ISOSTORE_START) && (hr <= ISS_E_ISOSTORE_END))
{
switch (hr)
{
case ISS_E_ISOSTORE :
case ISS_E_OPEN_STORE_FILE :
case ISS_E_OPEN_FILE_MAPPING :
case ISS_E_MAP_VIEW_OF_FILE :
case ISS_E_GET_FILE_SIZE :
case ISS_E_CREATE_MUTEX :
case ISS_E_LOCK_FAILED :
case ISS_E_FILE_WRITE :
case ISS_E_SET_FILE_POINTER :
case ISS_E_CREATE_DIR :
case ISS_E_CORRUPTED_STORE_FILE :
case ISS_E_STORE_VERSION :
case ISS_E_FILE_NOT_MAPPED :
case ISS_E_BLOCK_SIZE_TOO_SMALL :
case ISS_E_ALLOC_TOO_LARGE :
case ISS_E_USAGE_WILL_EXCEED_QUOTA :
case ISS_E_TABLE_ROW_NOT_FOUND :
case ISS_E_DEPRECATE :
case ISS_E_CALLER :
case ISS_E_PATH_LENGTH :
case ISS_E_MACHINE :
case ISS_E_STORE_NOT_OPEN :
case ISS_E_MACHINE_DACL :
COMPlusThrowHR(hr);
break;
default :
_ASSERTE(!"Unknown hr");
}
}
COMPlusThrowHR(hr);
}
StackWalkAction COMIsolatedStorage::StackWalkCallBack(
CrawlFrame* pCf, PVOID ppv)
{
CONTRACTL {
THROWS;
GC_TRIGGERS;
MODE_COOPERATIVE;
} CONTRACTL_END;
static MethodTable *s_pIsoStore = NULL;
if (s_pIsoStore == NULL)
s_pIsoStore = g_Mscorlib.GetClass(CLASS__ISS_STORE);
static MethodTable *s_pIsoStoreFile = NULL;
if (s_pIsoStoreFile == NULL)
s_pIsoStoreFile = g_Mscorlib.GetClass(CLASS__ISS_STORE_FILE);
static MethodTable *s_pIsoStoreFileStream = NULL;
if (s_pIsoStoreFileStream == NULL)
s_pIsoStoreFileStream = g_Mscorlib.GetClass(CLASS__ISS_STORE_FILE_STREAM);
// Get the function descriptor for this frame...
MethodDesc *pMeth = pCf->GetFunction();
MethodTable *pMT = pMeth->GetMethodTable();
// Skip the Isolated Store and all it's sub classes..
if ((pMT == s_pIsoStore) ||
(pMT == s_pIsoStoreFile) ||
(pMT == s_pIsoStoreFileStream))
{
LOG((LF_STORE, LL_INFO10000, "StackWalk Continue %s\n",
pMeth->m_pszDebugMethodName));
return SWA_CONTINUE;
}
*(PVOID *)ppv = pMeth->GetModule()->GetAssembly();
return SWA_ABORT;
}
FCIMPL0(Object*, COMIsolatedStorage::GetCaller)
{
CONTRACTL {
THROWS;
DISABLED(GC_TRIGGERS); // FCALLS with HELPER frames have issues with GC_TRIGGERS
MODE_COOPERATIVE;
SO_TOLERANT;
} CONTRACTL_END;
OBJECTREF refRetVal = NULL;
HELPER_METHOD_FRAME_BEGIN_RET_ATTRIB_1(Frame::FRAME_ATTR_RETURNOBJ, refRetVal);
Assembly *pAssem = NULL;
if (StackWalkFunctions(GetThread(), StackWalkCallBack, (VOID*)&pAssem)
== SWA_FAILED)
ThrowISS(ISS_E_CALLER);
if (pAssem == NULL)
ThrowISS(ISS_E_CALLER);
PREFIX_ASSUME(pAssem != NULL);
#ifdef _DEBUG
LOG((LF_STORE, LL_INFO10000, "StackWalk Found %s\n", pAssem->GetSimpleName()));
#endif
refRetVal = pAssem->GetExposedObject();
HELPER_METHOD_FRAME_END();
return OBJECTREFToObject(refRetVal);
}
FCIMPLEND
FCIMPL1(UINT64, COMIsolatedStorageFile::GetUsage, LPVOID handle)
{
CONTRACTL {
THROWS;
DISABLED(GC_TRIGGERS); // FCALLS with HELPER frames have issues with GC_TRIGGERS
MODE_COOPERATIVE;
SO_TOLERANT;
} CONTRACTL_END;
UINT64 retVal = 0;
HELPER_METHOD_FRAME_BEGIN_RET_0();
HRESULT hr = S_OK;
AccountingInfo *pAI = (AccountingInfo*) handle;
if (pAI == NULL)
COMIsolatedStorage::ThrowISS(ISS_E_STORE_NOT_OPEN);
PREFIX_ASSUME(pAI != NULL);
hr = pAI->GetUsage(&retVal);
if (FAILED(hr))
COMIsolatedStorage::ThrowISS(hr);
HELPER_METHOD_FRAME_END();
return retVal;
}
FCIMPLEND
FCIMPL1(void, COMIsolatedStorageFile::Close, LPVOID handle)
{
CONTRACTL {
THROWS;
DISABLED(GC_TRIGGERS); // FCALLS with HELPER frames have issues with GC_TRIGGERS
MODE_COOPERATIVE;
SO_TOLERANT;
} CONTRACTL_END;
HELPER_METHOD_FRAME_BEGIN_0();
AccountingInfo *pAI = (AccountingInfo*) handle;
if (pAI != NULL)
delete pAI;
HELPER_METHOD_FRAME_END();
}
FCIMPLEND
FCIMPL2(void, COMIsolatedStorageFile::Lock, LPVOID handle, CLR_BOOL fLock)
{
CONTRACTL {
THROWS;
DISABLED(GC_TRIGGERS); // FCALLS with HELPER frames have issues with GC_TRIGGERS
MODE_COOPERATIVE;
SO_TOLERANT;
} CONTRACTL_END;
HELPER_METHOD_FRAME_BEGIN_0();
AccountingInfo *pAI = (AccountingInfo*) handle;
_ASSERTE(pAI);
if (fLock)
AccountingInfo::AcquireLock(pAI);
else
AccountingInfo::ReleaseLock(pAI);
HELPER_METHOD_FRAME_END();
}
FCIMPLEND
FCIMPL2(LPVOID, COMIsolatedStorageFile::Open, StringObject* fileNameUNSAFE, StringObject* syncNameUNSAFE)
{
CONTRACTL {
THROWS;
DISABLED(GC_TRIGGERS); // FCALLS with HELPER frames have issues with GC_TRIGGERS
MODE_COOPERATIVE;
SO_TOLERANT;
} CONTRACTL_END;
LPVOID retVal = NULL;
STRINGREF fileName = (STRINGREF) fileNameUNSAFE;
STRINGREF syncName = (STRINGREF) syncNameUNSAFE;
HELPER_METHOD_FRAME_BEGIN_RET_2(fileName, syncName);
HRESULT hr;
AccountingInfo *pAI = new AccountingInfo(fileName->GetBuffer(), syncName->GetBuffer());
hr = pAI->Init();
if (FAILED(hr))
COMIsolatedStorage::ThrowISS(hr);
retVal = pAI;
HELPER_METHOD_FRAME_END();
return retVal;
}
FCIMPLEND
FCIMPL4(void, COMIsolatedStorageFile::Reserve, LPVOID handle, UINT64* pqwQuota, UINT64* pqwReserve, CLR_BOOL fFree)
{
CONTRACTL {
THROWS;
DISABLED(GC_TRIGGERS); // FCALLS with HELPER frames have issues with GC_TRIGGERS
MODE_COOPERATIVE;
SO_TOLERANT;
} CONTRACTL_END;
HELPER_METHOD_FRAME_BEGIN_0();
HRESULT hr;
AccountingInfo *pAI = (AccountingInfo*) handle;
if (pAI == NULL)
COMIsolatedStorage::ThrowISS(ISS_E_STORE_NOT_OPEN);
PREFIX_ASSUME(pAI != NULL);
hr = pAI->Reserve(*(pqwQuota), *(pqwReserve), fFree);