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

  1. /******************************************************************************
  2. Copyright (c) 2001 Microsoft Corporation
  3. Module Name:
  4. FTSWrap.cpp
  5. Abstract:
  6. Implementation of SearchEngine::WrapperFTS
  7. Revision History:
  8. Ghim-Sim Chua (gschua) 06/01/2000
  9. created
  10. ******************************************************************************/
  11. #include "stdafx.h"
  12. #include "msitstg.h"
  13. #include "itrs.h"
  14. #include "itdb.h"
  15. #include "iterror.h"
  16. #include "itgroup.h"
  17. #include "itpropl.h"
  18. #include "itquery.h"
  19. #include "itcc.h"
  20. #include "ftsobj.h"
  21. #include "fs.h"
  22. ////////////////////////////////////////////////////////////////////////////////
  23. static bool local_ExpandURL( /*[in ]*/ Taxonomy::Updater& updater ,
  24. /*[in ]*/ const MPC::wstring& strSrc ,
  25. /*[in ]*/ LPCWSTR szPrefix ,
  26. /*[out]*/ MPC::wstring& strDst )
  27. {
  28. strDst = szPrefix;
  29. strDst += strSrc;
  30. if(SUCCEEDED(updater.ExpandURL( strDst )))
  31. {
  32. if(MPC::FileSystemObject::IsFile( strDst.c_str() )) return true;
  33. }
  34. return false;
  35. }
  36. static void local_GenerateFullURL( /*[in ]*/ Taxonomy::Updater& updater ,
  37. /*[in ]*/ const MPC::wstring& strSrc ,
  38. /*[out]*/ MPC::wstring& strDst )
  39. {
  40. if(strSrc.size())
  41. {
  42. if(local_ExpandURL( updater, strSrc, L"%HELP_LOCATION%\\", strDst )) return;
  43. if(local_ExpandURL( updater, strSrc, L"%WINDIR%\\Help\\" , strDst )) return;
  44. }
  45. strDst = L"";
  46. }
  47. ////////////////////////////////////////////////////////////////////////////////
  48. SearchEngine::WrapperFTS::WrapperFTS()
  49. {
  50. // SEARCH_OBJECT_LIST m_objects;
  51. // SEARCH_RESULT_SET m_results;
  52. // SEARCH_RESULT_SORTSET m_resultsSorted;
  53. MPC::LocalizeString( IDS_HELPSVC_SEMGR_OWNER , m_bstrOwner , /*fMUI*/true );
  54. MPC::LocalizeString( IDS_HELPSVC_SEMGR_FTS_NAME, m_bstrName , /*fMUI*/true );
  55. MPC::LocalizeString( IDS_HELPSVC_SEMGR_FTS_DESC, m_bstrDescription, /*fMUI*/true );
  56. m_bstrHelpURL = L"hcp://system/blurbs/ftshelp.htm";
  57. m_bstrID = L"9A22481C-1795-46f3-8CCA-7D78E9E54112";
  58. }
  59. SearchEngine::WrapperFTS::~WrapperFTS()
  60. {
  61. Thread_Wait();
  62. ReleaseAll();
  63. }
  64. HRESULT SearchEngine::WrapperFTS::GetParamDefinition( /*[out]*/ const ParamItem_Definition*& lst, /*[out]*/ int& len )
  65. {
  66. static const ParamItem_Definition c_lst[] =
  67. {
  68. { PARAM_BOOL, VARIANT_FALSE, VARIANT_TRUE , L"TITLEONLY", IDS_HELPSVC_TITLE_ONLY, NULL, L"false" },
  69. { PARAM_BOOL, VARIANT_FALSE, VARIANT_TRUE , L"STEMMING" , IDS_HELPSVC_STEMMING , NULL, L"false" },
  70. { PARAM_BOOL, VARIANT_FALSE, VARIANT_FALSE, L"UI_BULLET", 0 , NULL, L"false" },
  71. };
  72. lst = c_lst;
  73. len = ARRAYSIZE(c_lst);
  74. return S_OK;
  75. }
  76. ////////////////////////////////////////////////////////////////////////////////
  77. void SearchEngine::WrapperFTS::ReleaseAll()
  78. {
  79. ReleaseSearchResults();
  80. m_objects.clear();
  81. }
  82. void SearchEngine::WrapperFTS::ReleaseSearchResults()
  83. {
  84. m_results .clear();
  85. m_resultsSorted.clear();
  86. }
  87. ////////////////////////////////////////////////////////////////////////////////
  88. HRESULT SearchEngine::WrapperFTS::ExecQuery()
  89. {
  90. __HCP_FUNC_ENTRY( "SearchEngine::WrapperFTS::ExecQuery" );
  91. HRESULT hr;
  92. long lCount;
  93. long lIndex = 0;
  94. MPC::WStringSet wordsSet;
  95. MPC::WStringList wordsList;
  96. if(m_bEnabled)
  97. {
  98. CComBSTR bstrName;
  99. VARIANT* v;
  100. bool bTitle;
  101. bool bStemming;
  102. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::LocalizeString( IDS_HELPSVC_SEMGR_FTS_NAME, bstrName, /*fMUI*/true ));
  103. if(m_bstrQueryString.Length() == 0)
  104. {
  105. __MPC_SET_WIN32_ERROR_AND_EXIT(hr, ERROR_INVALID_DATA);
  106. }
  107. __MPC_EXIT_IF_METHOD_FAILS(hr, Initialize());
  108. //
  109. // Check if search in titles only
  110. //
  111. v = GetParamInternal( L"TITLEONLY" );
  112. bTitle = (v && v->vt == VT_BOOL && v->boolVal) ? true : false;
  113. //
  114. // Check if stemming is turned on
  115. //
  116. v = GetParamInternal( L"STEMMING" );
  117. bStemming = (v && v->vt == VT_BOOL && v->boolVal) ? true : false;
  118. //
  119. // Compute the code page each query, as the user may have changed the language using MUI between queries
  120. //
  121. UINT cp = CP_ACP;
  122. WCHAR wchLocale[10];
  123. if (GetLocaleInfo(m_ths.GetLanguage(), LOCALE_IDEFAULTANSICODEPAGE, wchLocale, ARRAYSIZE(wchLocale)))
  124. cp = wcstoul(wchLocale, NULL, 10);
  125. else
  126. cp = CP_ACP;
  127. //
  128. // Execute the queries
  129. //
  130. for(SEARCH_OBJECT_LIST_ITER it = m_objects.begin(); (it != m_objects.end()) && (!Thread_IsAborted()); it++)
  131. {
  132. (void)it->Query( m_bstrQueryString, bTitle, bStemming, m_results, wordsSet, cp );
  133. }
  134. if(Thread_IsAborted()) __MPC_SET_ERROR_AND_EXIT(hr, E_ABORT);
  135. for(SEARCH_RESULT_SET_ITER it2 = m_results.begin(); (it2 != m_results.end()) && (!Thread_IsAborted()); it2++)
  136. {
  137. m_resultsSorted.insert( &(*it2) );
  138. }
  139. if(Thread_IsAborted()) __MPC_SET_ERROR_AND_EXIT(hr, E_ABORT);
  140. //
  141. // Copy the Highlight words from set to list
  142. //
  143. for(MPC::WStringSetIter itString = wordsSet.begin(); (itString != wordsSet.end()) && (!Thread_IsAborted()); itString++)
  144. {
  145. wordsList.push_back( *itString );
  146. }
  147. if(Thread_IsAborted()) __MPC_SET_ERROR_AND_EXIT(hr, E_ABORT);
  148. //
  149. // Store Highlight words in safe array
  150. //
  151. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::ConvertListToSafeArray( wordsList, m_vKeywords, VT_VARIANT ));
  152. }
  153. hr = S_OK;
  154. __MPC_FUNC_CLEANUP;
  155. Thread_Abort();
  156. //
  157. // Call the SearchManager's OnComplete
  158. //
  159. (void)m_pSEMgr->WrapperComplete( hr, this );
  160. __MPC_FUNC_EXIT(hr);
  161. }
  162. STDMETHODIMP SearchEngine::WrapperFTS::get_SearchTerms( /*[out, retval]*/ VARIANT *pVal )
  163. {
  164. MPC::SmartLock<_ThreadModel> lock( this );
  165. return ::VariantCopy( pVal, &m_vKeywords );
  166. }
  167. HRESULT SearchEngine::WrapperFTS::Initialize()
  168. {
  169. __HCP_FUNC_ENTRY( "SearchEngine::WrapperFTS::Initialize" );
  170. HRESULT hr;
  171. MPC::SmartLock<_ThreadModel> lock( this );
  172. Taxonomy::Settings ts( m_ths );
  173. JetBlue::SessionHandle handle;
  174. JetBlue::Database* db;
  175. Taxonomy::Updater updater;
  176. Taxonomy::RS_FullTextSearch* rsFTS;
  177. Taxonomy::RS_Scope* rsSCOPE;
  178. long ID_scope = -1;
  179. bool fFound;
  180. //
  181. // Clean previous search results.
  182. //
  183. //ReleaseSearchResults();
  184. ReleaseAll();
  185. __MPC_EXIT_IF_METHOD_FAILS(hr, ts .GetDatabase ( handle, db, /*fReadOnly*/true ));
  186. __MPC_EXIT_IF_METHOD_FAILS(hr, updater.Init ( ts , db ));
  187. __MPC_EXIT_IF_METHOD_FAILS(hr, updater.GetFullTextSearch( &rsFTS ));
  188. __MPC_EXIT_IF_METHOD_FAILS(hr, updater.GetScope ( &rsSCOPE ));
  189. ////////////////////////////////////////
  190. if(m_bstrScope)
  191. {
  192. __MPC_EXIT_IF_METHOD_FAILS(hr, rsSCOPE->Seek_ByID( m_bstrScope, &fFound ));
  193. if(fFound)
  194. {
  195. ID_scope = rsSCOPE->m_ID_scope;
  196. }
  197. }
  198. if(ID_scope == -1)
  199. {
  200. __MPC_EXIT_IF_METHOD_FAILS(hr, rsSCOPE->Seek_ByID( L"<SYSTEM>", &fFound ));
  201. if(fFound)
  202. {
  203. ID_scope = rsSCOPE->m_ID_scope;
  204. }
  205. }
  206. ////////////////////////////////////////
  207. //
  208. // Create the search objects.
  209. //
  210. __MPC_EXIT_IF_METHOD_FAILS(hr, rsFTS->Move( 0, JET_MoveFirst, &fFound ));
  211. while(fFound)
  212. {
  213. if(rsFTS->m_ID_scope == ID_scope)
  214. {
  215. CFTSObject& obj = *(m_objects.insert( m_objects.end() ));
  216. CFTSObject::Config& cfg = obj.GetConfig();
  217. local_GenerateFullURL( updater, rsFTS->m_strCHM, cfg.m_strCHMFilename );
  218. local_GenerateFullURL( updater, rsFTS->m_strCHQ, cfg.m_strCHQFilename );
  219. if(cfg.m_strCHQFilename.size())
  220. {
  221. cfg.m_fCombined = true;
  222. }
  223. }
  224. __MPC_EXIT_IF_METHOD_FAILS(hr, rsFTS->Move( 0, JET_MoveNext, &fFound ));
  225. }
  226. hr = S_OK;
  227. __MPC_FUNC_CLEANUP;
  228. __MPC_FUNC_EXIT(hr);
  229. }
  230. ////////////////////////////////////////////////////////////////////////////////
  231. STDMETHODIMP SearchEngine::WrapperFTS::Result( /*[in]*/ long lStart, /*[in]*/ long lEnd, /*[out,retval]*/ IPCHCollection* *ppC )
  232. {
  233. __HCP_FUNC_ENTRY( "SearchEngine::WrapperFTS::Result" );
  234. HRESULT hr;
  235. MPC::SmartLock<_ThreadModel> lock( this );
  236. CComPtr<CPCHCollection> pColl;
  237. __MPC_PARAMCHECK_BEGIN(hr)
  238. __MPC_PARAMCHECK_POINTER_AND_SET(ppC,NULL);
  239. __MPC_PARAMCHECK_END();
  240. //
  241. // Create the Enumerator and fill it with jobs.
  242. //
  243. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &pColl ));
  244. if(m_bEnabled)
  245. {
  246. long lCount = 0;
  247. for(SEARCH_RESULT_SORTSET_ITER it = m_resultsSorted.begin(); (lCount < m_lNumResult) && (it != m_resultsSorted.end()); it++, lCount++)
  248. {
  249. //
  250. // if there is a URL
  251. //
  252. if(lCount >= lStart &&
  253. lCount < lEnd )
  254. {
  255. CComPtr<ResultItem> pRIObj;
  256. //
  257. // Create the item to be inserted into the list
  258. //
  259. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &pRIObj ));
  260. {
  261. ResultItem_Data& data = pRIObj->Data();
  262. SEARCH_RESULT* res = *it;
  263. data.m_bstrTitle = res->bstrTopicName;
  264. data.m_bstrLocation = res->bstrLocation;
  265. data.m_bstrURI = res->bstrTopicURL;
  266. }
  267. //
  268. // Add to enumerator
  269. //
  270. __MPC_EXIT_IF_METHOD_FAILS(hr, pColl->AddItem( pRIObj ));
  271. }
  272. }
  273. }
  274. __MPC_EXIT_IF_METHOD_FAILS(hr, pColl.QueryInterface( ppC ));
  275. hr = S_OK;
  276. __MPC_FUNC_CLEANUP;
  277. __MPC_FUNC_EXIT(hr);
  278. }
  279. ////////////////////////////////////////////////////////////////////////////////
  280. STDMETHODIMP SearchEngine::WrapperFTS::AbortQuery()
  281. {
  282. //
  283. // Abort any threads still running
  284. //
  285. Thread_Abort();
  286. return S_OK;
  287. }
  288. STDMETHODIMP SearchEngine::WrapperFTS::ExecAsyncQuery()
  289. {
  290. __HCP_FUNC_ENTRY( "SearchEngine::WrapperFTS::ExecAsyncQuery" );
  291. HRESULT hr;
  292. //
  293. // Create a thread to execute the query
  294. //
  295. __MPC_EXIT_IF_METHOD_FAILS(hr, Thread_Start( this, ExecQuery, NULL ));
  296. hr = S_OK;
  297. __MPC_FUNC_CLEANUP;
  298. __MPC_FUNC_EXIT(hr);
  299. }
  300. ////////////////////////////////////////////////////////////////////////////////
  301. HRESULT SearchEngine::WrapperItem__Create_FullTextSearch( /*[out]*/ CComPtr<IPCHSEWrapperInternal>& pVal )
  302. {
  303. __HCP_FUNC_ENTRY( "CPCHSEWrapperItem__Create_FullTextSearch" );
  304. HRESULT hr;
  305. CComPtr<SearchEngine::WrapperFTS> pFTS;
  306. __MPC_EXIT_IF_METHOD_FAILS(hr, MPC::CreateInstance( &pFTS ));
  307. pVal = pFTS;
  308. hr = S_OK;
  309. __HCP_FUNC_CLEANUP;
  310. __HCP_FUNC_EXIT(hr);
  311. }