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.
 
 
 
 
 
 

421 lines
12 KiB

/******************************************************************************
Copyright (c) 2001 Microsoft Corporation
Module Name:
FTSWrap.cpp
Abstract:
Implementation of SearchEngine::WrapperFTS
Revision History:
Ghim-Sim Chua (gschua) 06/01/2000
created
******************************************************************************/
#include "stdafx.h"
#include "msitstg.h"
#include "itrs.h"
#include "itdb.h"
#include "iterror.h"
#include "itgroup.h"
#include "itpropl.h"
#include "itquery.h"
#include "itcc.h"
#include "ftsobj.h"
#include "fs.h"
////////////////////////////////////////////////////////////////////////////////
static bool local_ExpandURL( /*[in ]*/ Taxonomy::Updater& updater ,
/*[in ]*/ const MPC::wstring& strSrc ,
/*[in ]*/ LPCWSTR szPrefix ,
/*[out]*/ MPC::wstring& strDst )
{
strDst = szPrefix;
strDst += strSrc;
if(SUCCEEDED(updater.ExpandURL( strDst )))
{
if(MPC::FileSystemObject::IsFile( strDst.c_str() )) return true;
}
return false;
}
static void local_GenerateFullURL( /*[in ]*/ Taxonomy::Updater& updater ,
/*[in ]*/ const MPC::wstring& strSrc ,
/*[out]*/ MPC::wstring& strDst )
{
if(strSrc.size())
{
if(local_ExpandURL( updater, strSrc, L"%HELP_LOCATION%\\", strDst )) return;
if(local_ExpandURL( updater, strSrc, L"%WINDIR%\\Help\\" , strDst )) return;
}
strDst = L"";
}
////////////////////////////////////////////////////////////////////////////////
SearchEngine::WrapperFTS::WrapperFTS()
{
// SEARCH_OBJECT_LIST m_objects;
// SEARCH_RESULT_SET m_results;
// SEARCH_RESULT_SORTSET m_resultsSorted;
MPC::LocalizeString( IDS_HELPSVC_SEMGR_OWNER , m_bstrOwner , /*fMUI*/true );
MPC::LocalizeString( IDS_HELPSVC_SEMGR_FTS_NAME, m_bstrName , /*fMUI*/true );
MPC::LocalizeString( IDS_HELPSVC_SEMGR_FTS_DESC, m_bstrDescription, /*fMUI*/true );
m_bstrHelpURL = L"hcp://system/blurbs/ftshelp.htm";
m_bstrID = L"9A22481C-1795-46f3-8CCA-7D78E9E54112";
}
SearchEngine::WrapperFTS::~WrapperFTS()
{
Thread_Wait();
ReleaseAll();
}
HRESULT SearchEngine::WrapperFTS::GetParamDefinition( /*[out]*/ const ParamItem_Definition*& lst, /*[out]*/ int& len )
{
static const ParamItem_Definition c_lst[] =
{
{ PARAM_BOOL, VARIANT_FALSE, VARIANT_TRUE , L"TITLEONLY", IDS_HELPSVC_TITLE_ONLY, NULL, L"false" },
{ PARAM_BOOL, VARIANT_FALSE, VARIANT_TRUE , L"STEMMING" , IDS_HELPSVC_STEMMING , NULL, L"false" },
{ PARAM_BOOL, VARIANT_FALSE, VARIANT_FALSE, L"UI_BULLET", 0 , NULL, L"false" },
};
lst = c_lst;
len = ARRAYSIZE(c_lst);
return S_OK;
}
////////////////////////////////////////////////////////////////////////////////
void SearchEngine::WrapperFTS::ReleaseAll()
{
ReleaseSearchResults();
m_objects.clear();
}
void SearchEngine::WrapperFTS::ReleaseSearchResults()
{
m_results .clear();
m_resultsSorted.clear();
}
////////////////////////////////////////////////////////////////////////////////
HRESULT SearchEngine::WrapperFTS::ExecQuery()
{
__HCP_FUNC_ENTRY( "SearchEngine::WrapperFTS::ExecQuery" );
HRESULT hr;
long lCount;
long lIndex = 0;
MPC::WStringSet wordsSet;
MPC::WStringList wordsList;
if(m_bEnabled)
{
CComBSTR bstrName;
VARIANT* v;
bool bTitle;
bool bStemming;
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::LocalizeString( IDS_HELPSVC_SEMGR_FTS_NAME, bstrName, /*fMUI*/true ));
if(m_bstrQueryString.Length() == 0)
{
__MPC_SET_WIN32_ERROR_AND_EXIT(hr, ERROR_INVALID_DATA);
}
__MPC_EXIT_IF_METHOD_FAILS(hr, Initialize());
//
// Check if search in titles only
//
v = GetParamInternal( L"TITLEONLY" );
bTitle = (v && v->vt == VT_BOOL && v->boolVal) ? true : false;
//
// Check if stemming is turned on
//
v = GetParamInternal( L"STEMMING" );
bStemming = (v && v->vt == VT_BOOL && v->boolVal) ? true : false;
//
// Compute the code page each query, as the user may have changed the language using MUI between queries
//
UINT cp = CP_ACP;
WCHAR wchLocale[10];
if (GetLocaleInfo(m_ths.GetLanguage(), LOCALE_IDEFAULTANSICODEPAGE, wchLocale, ARRAYSIZE(wchLocale)))
cp = wcstoul(wchLocale, NULL, 10);
else
cp = CP_ACP;
//
// Execute the queries
//
for(SEARCH_OBJECT_LIST_ITER it = m_objects.begin(); (it != m_objects.end()) && (!Thread_IsAborted()); it++)
{
(void)it->Query( m_bstrQueryString, bTitle, bStemming, m_results, wordsSet, cp );
}
if(Thread_IsAborted()) __MPC_SET_ERROR_AND_EXIT(hr, E_ABORT);
for(SEARCH_RESULT_SET_ITER it2 = m_results.begin(); (it2 != m_results.end()) && (!Thread_IsAborted()); it2++)
{
m_resultsSorted.insert( &(*it2) );
}
if(Thread_IsAborted()) __MPC_SET_ERROR_AND_EXIT(hr, E_ABORT);
//
// Copy the Highlight words from set to list
//
for(MPC::WStringSetIter itString = wordsSet.begin(); (itString != wordsSet.end()) && (!Thread_IsAborted()); itString++)
{
wordsList.push_back( *itString );
}
if(Thread_IsAborted()) __MPC_SET_ERROR_AND_EXIT(hr, E_ABORT);
//
// Store Highlight words in safe array
//
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::ConvertListToSafeArray( wordsList, m_vKeywords, VT_VARIANT ));
}
hr = S_OK;
__MPC_FUNC_CLEANUP;
Thread_Abort();
//
// Call the SearchManager's OnComplete
//
(void)m_pSEMgr->WrapperComplete( hr, this );
__MPC_FUNC_EXIT(hr);
}
STDMETHODIMP SearchEngine::WrapperFTS::get_SearchTerms( /*[out, retval]*/ VARIANT *pVal )
{
MPC::SmartLock<_ThreadModel> lock( this );
return ::VariantCopy( pVal, &m_vKeywords );
}
HRESULT SearchEngine::WrapperFTS::Initialize()
{
__HCP_FUNC_ENTRY( "SearchEngine::WrapperFTS::Initialize" );
HRESULT hr;
MPC::SmartLock<_ThreadModel> lock( this );
Taxonomy::Settings ts( m_ths );
JetBlue::SessionHandle handle;
JetBlue::Database* db;
Taxonomy::Updater updater;
Taxonomy::RS_FullTextSearch* rsFTS;
Taxonomy::RS_Scope* rsSCOPE;
long ID_scope = -1;
bool fFound;
//
// Clean previous search results.
//
//ReleaseSearchResults();
ReleaseAll();
__MPC_EXIT_IF_METHOD_FAILS(hr, ts .GetDatabase ( handle, db, /*fReadOnly*/true ));
__MPC_EXIT_IF_METHOD_FAILS(hr, updater.Init ( ts , db ));
__MPC_EXIT_IF_METHOD_FAILS(hr, updater.GetFullTextSearch( &rsFTS ));
__MPC_EXIT_IF_METHOD_FAILS(hr, updater.GetScope ( &rsSCOPE ));
////////////////////////////////////////
if(m_bstrScope)
{
__MPC_EXIT_IF_METHOD_FAILS(hr, rsSCOPE->Seek_ByID( m_bstrScope, &fFound ));
if(fFound)
{
ID_scope = rsSCOPE->m_ID_scope;
}
}
if(ID_scope == -1)
{
__MPC_EXIT_IF_METHOD_FAILS(hr, rsSCOPE->Seek_ByID( L"<SYSTEM>", &fFound ));
if(fFound)
{
ID_scope = rsSCOPE->m_ID_scope;
}
}
////////////////////////////////////////
//
// Create the search objects.
//
__MPC_EXIT_IF_METHOD_FAILS(hr, rsFTS->Move( 0, JET_MoveFirst, &fFound ));
while(fFound)
{
if(rsFTS->m_ID_scope == ID_scope)
{
CFTSObject& obj = *(m_objects.insert( m_objects.end() ));
CFTSObject::Config& cfg = obj.GetConfig();
local_GenerateFullURL( updater, rsFTS->m_strCHM, cfg.m_strCHMFilename );
local_GenerateFullURL( updater, rsFTS->m_strCHQ, cfg.m_strCHQFilename );
if(cfg.m_strCHQFilename.size())
{
cfg.m_fCombined = true;
}
}
__MPC_EXIT_IF_METHOD_FAILS(hr, rsFTS->Move( 0, JET_MoveNext, &fFound ));
}
hr = S_OK;
__MPC_FUNC_CLEANUP;
__MPC_FUNC_EXIT(hr);
}
////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP SearchEngine::WrapperFTS::Result( /*[in]*/ long lStart, /*[in]*/ long lEnd, /*[out,retval]*/ IPCHCollection* *ppC )
{
__HCP_FUNC_ENTRY( "SearchEngine::WrapperFTS::Result" );
HRESULT hr;
MPC::SmartLock<_ThreadModel> lock( this );
CComPtr<CPCHCollection> pColl;
__MPC_PARAMCHECK_BEGIN(hr)
__MPC_PARAMCHECK_POINTER_AND_SET(ppC,NULL);
__MPC_PARAMCHECK_END();
//
// Create the Enumerator and fill it with jobs.
//
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &pColl ));
if(m_bEnabled)
{
long lCount = 0;
for(SEARCH_RESULT_SORTSET_ITER it = m_resultsSorted.begin(); (lCount < m_lNumResult) && (it != m_resultsSorted.end()); it++, lCount++)
{
//
// if there is a URL
//
if(lCount >= lStart &&
lCount < lEnd )
{
CComPtr<ResultItem> pRIObj;
//
// Create the item to be inserted into the list
//
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &pRIObj ));
{
ResultItem_Data& data = pRIObj->Data();
SEARCH_RESULT* res = *it;
data.m_bstrTitle = res->bstrTopicName;
data.m_bstrLocation = res->bstrLocation;
data.m_bstrURI = res->bstrTopicURL;
}
//
// Add to enumerator
//
__MPC_EXIT_IF_METHOD_FAILS(hr, pColl->AddItem( pRIObj ));
}
}
}
__MPC_EXIT_IF_METHOD_FAILS(hr, pColl.QueryInterface( ppC ));
hr = S_OK;
__MPC_FUNC_CLEANUP;
__MPC_FUNC_EXIT(hr);
}
////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP SearchEngine::WrapperFTS::AbortQuery()
{
//
// Abort any threads still running
//
Thread_Abort();
return S_OK;
}
STDMETHODIMP SearchEngine::WrapperFTS::ExecAsyncQuery()
{
__HCP_FUNC_ENTRY( "SearchEngine::WrapperFTS::ExecAsyncQuery" );
HRESULT hr;
//
// Create a thread to execute the query
//
__MPC_EXIT_IF_METHOD_FAILS(hr, Thread_Start( this, ExecQuery, NULL ));
hr = S_OK;
__MPC_FUNC_CLEANUP;
__MPC_FUNC_EXIT(hr);
}
////////////////////////////////////////////////////////////////////////////////
HRESULT SearchEngine::WrapperItem__Create_FullTextSearch( /*[out]*/ CComPtr<IPCHSEWrapperInternal>& pVal )
{
__HCP_FUNC_ENTRY( "CPCHSEWrapperItem__Create_FullTextSearch" );
HRESULT hr;
CComPtr<SearchEngine::WrapperFTS> pFTS;
__MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &pFTS ));
pVal = pFTS;
hr = S_OK;
__HCP_FUNC_CLEANUP;
__HCP_FUNC_EXIT(hr);
}