Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

409 lines
9.4 KiB

/******************************************************************************
Copyright (c) 1999-2000 Microsoft Corporation
Module Name:
OfflineCache_Master.cpp
Abstract:
Handles caching of database lookups, service-side.
Revision History:
Davide Massarenti (Dmassare) 07/17/2000
created
******************************************************************************/
#include "stdafx.h"
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
HRESULT OfflineCache::Query::Store( /*[in]*/ const MPC::wstring& strDir ,
/*[in]*/ const CPCHQueryResultCollection* pColl )
{
__HCP_FUNC_ENTRY( "OfflineCache::Query::Store" );
HRESULT hr;
if(m_fNull == false)
{
MPC::wstring strFile;
CComPtr<MPC::FileStream> stream;
__MPC_EXIT_IF_METHOD_FAILS(hr, InitFile ( strDir, strFile ));
__MPC_EXIT_IF_METHOD_FAILS(hr, SVC::SafeSave_Init( strFile, stream ));
//
// Create an IStream from the collection.
//
{
MPC::Serializer_IStream streamGen ( stream );
MPC::Serializer_Buffering streamGen2( streamGen );
__MPC_EXIT_IF_METHOD_FAILS(hr, pColl->Save( streamGen2 ));
__MPC_EXIT_IF_METHOD_FAILS(hr, streamGen2.Flush());
}
__MPC_EXIT_IF_METHOD_FAILS(hr, SVC::SafeSave_Finalize( strFile, stream ));
}
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
HRESULT OfflineCache::Query::Remove( /*[in]*/ const MPC::wstring& strDir )
{
__HCP_FUNC_ENTRY( "OfflineCache::Query::Remove" );
HRESULT hr;
if(m_fNull == false)
{
MPC::wstring strFile;
__MPC_EXIT_IF_METHOD_FAILS(hr, InitFile( strDir, strFile ));
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::DeleteFile( strFile, /*fForce*/true, /*fDelayed*/false ));
}
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
bool OfflineCache::SetOfHelpTopics::AreYouInterested( /*[in]*/ LPCWSTR szID ,
/*[in]*/ int iType )
{
int iDepth = 1;
switch(iType)
{
case ET_NODE :
case ET_SUBNODES :
case ET_SUBNODES_VISIBLE :
case ET_NODESANDTOPICS :
case ET_NODESANDTOPICS_VISIBLE:
case ET_TOPICS :
case ET_TOPICS_VISIBLE : break;
default : return false; // Not interested for now...
}
//
// Count the depth of the taxonomy node, we are only interested in the first two levels.
//
if(szID)
{
WCHAR c;
while((c = *szID++))
{
if(c == '/') iDepth++;
}
}
if(m_inst.m_fDesktop && iDepth < 4) return true;
if( iDepth < 3) return true;
return false;
}
HRESULT OfflineCache::SetOfHelpTopics::Store( /*[in]*/ LPCWSTR szID ,
/*[in]*/ int iType ,
/*[in]*/ const CPCHQueryResultCollection* pColl )
{
__HCP_FUNC_ENTRY( "OfflineCache::SetOfHelpTopics::Store" );
HRESULT hr;
QueryIter it;
__MPC_PARAMCHECK_BEGIN(hr)
__MPC_PARAMCHECK_NOTNULL(pColl);
__MPC_PARAMCHECK_END();
__MPC_EXIT_IF_METHOD_FAILS(hr, Find( szID, iType, it ));
if(it == m_lstQueries.end())
{
it = m_lstQueries.insert( m_lstQueries.end() );
it->m_strID = szID;
it->m_iType = iType;
it->m_iSequence = m_iLastSeq++;
it->m_fNull = (pColl->Size() == 0);
if(m_parent) __MPC_EXIT_IF_METHOD_FAILS(hr, m_parent->SetDirty());
}
//
// Persist to disk.
//
if(it->m_fNull == false)
{
MPC::wstring strDir;
__MPC_EXIT_IF_METHOD_FAILS(hr, InitDir( strDir ));
__MPC_EXIT_IF_METHOD_FAILS(hr, it->Store( strDir, pColl ));
}
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
HRESULT OfflineCache::SetOfHelpTopics::RemoveQueries()
{
__HCP_FUNC_ENTRY( "OfflineCache::SetOfHelpTopics::RemoveQueries" );
HRESULT hr;
MPC::wstring strDir;
QueryIter it;
__MPC_EXIT_IF_METHOD_FAILS(hr, InitDir( strDir ));
for(it = m_lstQueries.begin(); it != m_lstQueries.end(); it++)
{
__MPC_EXIT_IF_METHOD_FAILS(hr, it->Remove( strDir ));
}
m_lstQueries.clear();
m_iLastSeq = 0;
{
MPC::FileSystemObject fso( strDir.c_str() );
__MPC_EXIT_IF_METHOD_FAILS(hr, fso.DeleteChildren( /*fForce*/true, /*fComplain*/false ));
}
if(m_parent) __MPC_EXIT_IF_METHOD_FAILS(hr, m_parent->SetDirty());
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
HRESULT OfflineCache::Root::SetDirty()
{
m_fDirty = true;
return S_OK;
}
HRESULT OfflineCache::Root::DisableSave()
{
MPC::SmartLock<_ThreadModel> lock( this );
m_dwDisableSave++;
return S_OK;
}
HRESULT OfflineCache::Root::EnableSave()
{
__HCP_FUNC_ENTRY( "OfflineCache::Root::EnableSave" );
HRESULT hr;
MPC::SmartLock<_ThreadModel> lock( this );
if(m_dwDisableSave)
{
if(--m_dwDisableSave == 0)
{
__MPC_EXIT_IF_METHOD_FAILS(hr, Save());
}
}
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
HRESULT OfflineCache::Root::Save()
{
__HCP_FUNC_ENTRY( "OfflineCache::Root::Save" );
HRESULT hr;
if(m_fDirty && m_fMaster && m_dwDisableSave == 0) // Only master can write to the registry.
{
MPC::wstring strIndex;
CComPtr<MPC::FileStream> stream;
__MPC_EXIT_IF_METHOD_FAILS(hr, GetIndexFile ( strIndex ));
__MPC_EXIT_IF_METHOD_FAILS(hr, SVC::SafeSave_Init( strIndex, stream ));
//
// Create IStream from the collection.
//
{
MPC::Serializer_IStream streamGen ( stream );
MPC::Serializer_Buffering streamGen2( streamGen );
DWORD dwVer = s_dwVersion;
__MPC_EXIT_IF_METHOD_FAILS(hr, streamGen2 << dwVer );
__MPC_EXIT_IF_METHOD_FAILS(hr, streamGen2 << *this );
__MPC_EXIT_IF_METHOD_FAILS(hr, streamGen2.Flush());
}
__MPC_EXIT_IF_METHOD_FAILS(hr, SVC::SafeSave_Finalize( strIndex, stream ));
m_fDirty = false;
}
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
////////////////////////////////////////
HRESULT OfflineCache::Root::Import( /*[in]*/ const Taxonomy::Instance& inst )
{
__HCP_FUNC_ENTRY( "OfflineCache::Root::Import" );
HRESULT hr;
MPC::SmartLock<_ThreadModel> lock( this );
SKUIter it;
if(m_fMaster == false)
{
__MPC_SET_ERROR_AND_EXIT(hr, E_ACCESSDENIED);
}
__MPC_EXIT_IF_METHOD_FAILS(hr, Find( inst.m_ths, it ));
if(it == m_lstSKUs.end())
{
it = m_lstSKUs.insert( m_lstSKUs.end() );
it->ConnectToParent( this );
it->m_inst = inst;
m_fDirty = true;
}
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
////////////////////
HRESULT OfflineCache::Root::Remove( /*[in]*/ const Taxonomy::HelpSet& ths )
{
__HCP_FUNC_ENTRY( "OfflineCache::Root::Remove" );
HRESULT hr;
MPC::SmartLock<_ThreadModel> lock( this );
SKUIter it;
if(m_fMaster == false)
{
__MPC_SET_ERROR_AND_EXIT(hr, E_ACCESSDENIED);
}
__MPC_EXIT_IF_METHOD_FAILS(hr, Find( ths, it ));
if(it != m_lstSKUs.end())
{
(void)it->RemoveQueries();
m_lstSKUs.erase( it );
m_fDirty = true;
}
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
HRESULT OfflineCache::Root::Flush( /*[in]*/ bool fForce )
{
__HCP_FUNC_ENTRY( "OfflineCache::Root::Flush" );
HRESULT hr;
MPC::SmartLock<_ThreadModel> lock( this );
if(m_fMaster)
{
if(fForce) m_fDirty = true;
}
else
{
//
// On the slave side, Flush is like Reload.
//
__MPC_EXIT_IF_METHOD_FAILS(hr, Clean());
}
__MPC_EXIT_IF_METHOD_FAILS(hr, Save());
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}
////////////////////////////////////////
HRESULT OfflineCache::Root::SetReady( /*[in]*/ bool fReady )
{
__HCP_FUNC_ENTRY( "OfflineCache::Root::SetReady" );
HRESULT hr;
MPC::SmartLock<_ThreadModel> lock( this );
m_fReady = fReady;
m_fDirty = true;
hr = S_OK;
__HCP_FUNC_EXIT(hr);
}