536 lines
16 KiB
C++
536 lines
16 KiB
C++
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
|
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
|
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
|
// PARTICULAR PURPOSE.
|
|
//
|
|
// Copyright (c) Microsoft Corporation. All rights reserved
|
|
|
|
#include "csmcmd.h"
|
|
|
|
// Forward declarations
|
|
int EnumRoots();
|
|
int EnumRules();
|
|
int AddRoots(PCWSTR pszURL);
|
|
int RemoveRoots(PCWSTR pszURL);
|
|
int AddRule(BOOL fDefault, BOOL fInclude, BOOL fOverride, PCWSTR pszURL);
|
|
int RemoveRule(BOOL fDefault, PCWSTR pszURL);
|
|
int Revert();
|
|
int Reset();
|
|
int Reindex();
|
|
|
|
// Global objects used for command line parsing.
|
|
CExclFlagParam g_IncludeParam(L"include", L"exclude");
|
|
CExclFlagParam g_DefaultParam(L"default", L"user");
|
|
CFlagParam g_OverrideParam(L"override_children");
|
|
CFlagParam g_EnumRootsParam(L"enumerate_roots");
|
|
CFlagParam g_EnumRulesParam(L"enumerate_rules");
|
|
CSetValueParam g_AddRootParam(L"add_root");
|
|
CSetValueParam g_RemoveRootParam(L"remove_root");
|
|
CSetValueParam g_AddRuleParam(L"add_rule");
|
|
CSetValueParam g_RemoveRuleParam(L"remove_rule");
|
|
CFlagParam g_RevertParam(L"revert");
|
|
CFlagParam g_Reset(L"reset");
|
|
CFlagParam g_Reindex(L"reindex");
|
|
CFlagParam g_HelpParam(L"help");
|
|
CFlagParam g_AltHelpParam(L"?");
|
|
|
|
// List of all supported command line options.
|
|
CParamBase* Params[] =
|
|
{
|
|
&g_IncludeParam,
|
|
&g_DefaultParam,
|
|
&g_EnumRootsParam,
|
|
&g_EnumRulesParam,
|
|
&g_AddRootParam,
|
|
&g_RemoveRootParam,
|
|
&g_AddRuleParam,
|
|
&g_RemoveRuleParam,
|
|
&g_RevertParam,
|
|
&g_Reset,
|
|
&g_Reindex,
|
|
&g_HelpParam,
|
|
&g_AltHelpParam
|
|
};
|
|
|
|
// List of alternative options corresponding to CSM operations.
|
|
CParamBase* ExclusiveParams[] =
|
|
{
|
|
&g_EnumRootsParam,
|
|
&g_EnumRulesParam,
|
|
&g_AddRootParam,
|
|
&g_RemoveRootParam,
|
|
&g_AddRuleParam,
|
|
&g_RemoveRuleParam,
|
|
&g_RevertParam,
|
|
&g_Reset,
|
|
&g_Reindex,
|
|
&g_HelpParam,
|
|
&g_AltHelpParam,
|
|
};
|
|
|
|
// Command line options help text
|
|
const PCWSTR rgParamsHelp[] =
|
|
{
|
|
L"/enumerate_roots",
|
|
L"/enumerate_rules",
|
|
L"/add_root <new root path>",
|
|
L"/remove_root <root path to remove>",
|
|
L"/add_rule <rule URL> /[DEFAULT|USER] /[INCLUDE|EXCLUDE]",
|
|
L"/remove_rule <rule URL> /[DEFAULT|USER]",
|
|
L"/revert",
|
|
L"/reset",
|
|
L"/reindex",
|
|
L"/help or /? "
|
|
};
|
|
|
|
int PrintHelp()
|
|
{
|
|
wcout << L"NOTE: you must run this tool as an admin to perform functions" << endl;
|
|
wcout << L" that change the state of the index" << endl;
|
|
|
|
wcout << L"List of availible options:" << endl;
|
|
|
|
for (DWORD i = 0; i < ARRAYSIZE(rgParamsHelp); i++)
|
|
{
|
|
wcout << L"\t" << rgParamsHelp[i] << endl;
|
|
}
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
// CheckExcusiveParameters function validates that only one option
|
|
// from ExclusiveParams list is present in argument list
|
|
int CheckExcusiveParameters()
|
|
{
|
|
int iRes = ERROR_SUCCESS;
|
|
DWORD dwCount = 0;
|
|
for (int i = 0; i < ARRAYSIZE(ExclusiveParams); i++)
|
|
{
|
|
if (ExclusiveParams[i]->Exists())
|
|
{
|
|
dwCount++;
|
|
}
|
|
}
|
|
|
|
if (0 == dwCount)
|
|
{
|
|
wcout << L"Error: CSM operation parameter is expected!" << endl;
|
|
iRes = ERROR_INVALID_PARAMETER;
|
|
}
|
|
else if (1 < dwCount)
|
|
{
|
|
wcout << L"Error: Duplicated CSM operation parameters!" << endl;
|
|
iRes = ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
return iRes;
|
|
}
|
|
|
|
int wmain(int argc, wchar_t *argv[])
|
|
{
|
|
HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Parsing command line
|
|
int iRes = ParseParams(Params, ARRAYSIZE(Params), argc - 1, argv + 1);
|
|
if (ERROR_SUCCESS == iRes)
|
|
{
|
|
// Check that only one CSM operation parameter was referred
|
|
iRes = CheckExcusiveParameters();
|
|
if (ERROR_SUCCESS == iRes)
|
|
{
|
|
// Default catalog name will be used if /CATALOG option doesn't specify otherwise
|
|
if (g_HelpParam.Exists() || g_AltHelpParam.Exists())
|
|
{
|
|
iRes = PrintHelp();
|
|
}
|
|
else if (g_EnumRootsParam.Exists())
|
|
{
|
|
iRes = EnumRoots();
|
|
}
|
|
else if (g_EnumRulesParam.Exists())
|
|
{
|
|
iRes = EnumRules();
|
|
}
|
|
else if (g_AddRootParam.Exists())
|
|
{
|
|
iRes = AddRoots(g_AddRootParam.Get());
|
|
}
|
|
else if (g_RemoveRootParam.Exists())
|
|
{
|
|
iRes = RemoveRoots(g_RemoveRootParam.Get());
|
|
}
|
|
else if (g_AddRuleParam.Exists())
|
|
{
|
|
iRes = AddRule(g_DefaultParam.Exists() && g_DefaultParam.Get(),
|
|
g_IncludeParam.Exists() && g_IncludeParam.Get(),
|
|
g_OverrideParam.Exists(),
|
|
g_AddRuleParam.Get());
|
|
}
|
|
else if (g_RemoveRuleParam.Exists())
|
|
{
|
|
iRes = RemoveRule(g_DefaultParam.Exists() && g_DefaultParam.Get(),
|
|
g_RemoveRuleParam.Get());
|
|
}
|
|
else if (g_RevertParam.Exists())
|
|
{
|
|
iRes = Revert();
|
|
}
|
|
else if (g_Reset.Exists())
|
|
{
|
|
iRes = Reset();
|
|
}
|
|
else if (g_Reindex.Exists())
|
|
{
|
|
iRes = Reindex();
|
|
}
|
|
else
|
|
{
|
|
assert(!"Required parameter is missing!");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
iRes = PrintHelp();
|
|
}
|
|
}
|
|
|
|
CoUninitialize();
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int ReportHRESULTError(PCWSTR pszOpName, HRESULT hr)
|
|
{
|
|
int iErr = 0;
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
if (HRESULT_FACILITY(hr) == FACILITY_WIN32)
|
|
{
|
|
iErr = HRESULT_CODE(hr);
|
|
void *pMsgBuf;
|
|
|
|
::FormatMessageW(
|
|
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
|
|
NULL,
|
|
iErr,
|
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
|
(PWSTR) &pMsgBuf,
|
|
0, NULL );
|
|
|
|
wcout << endl << L"Error: " << pszOpName << L" failed with error " << iErr << L": " << (PWSTR)pMsgBuf << endl;
|
|
|
|
LocalFree(pMsgBuf);
|
|
}
|
|
else
|
|
{
|
|
wcout << endl << L"Error: " << pszOpName << L" failed with error 0x" << setbase(16) << hr << endl;
|
|
iErr = -1;
|
|
}
|
|
}
|
|
|
|
return iErr;
|
|
}
|
|
|
|
HRESULT CreateCatalogManager(ISearchCatalogManager **ppSearchCatalogManager)
|
|
{
|
|
*ppSearchCatalogManager = NULL;
|
|
|
|
ISearchManager *pSearchManager;
|
|
HRESULT hr = CoCreateInstance(CLSID_CSearchManager, NULL, CLSCTX_SERVER, IID_PPV_ARGS(&pSearchManager));
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pSearchManager->GetCatalog(L"SystemIndex", ppSearchCatalogManager);
|
|
pSearchManager->Release();
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CreateCrawlScopManager(ISearchCrawlScopeManager **ppSearchCrawlScopeManager)
|
|
{
|
|
*ppSearchCrawlScopeManager = NULL;
|
|
|
|
ISearchCatalogManager *pCatalogManager;
|
|
HRESULT hr = CreateCatalogManager(&pCatalogManager);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Crawl scope manager for that catalog
|
|
hr = pCatalogManager->GetCrawlScopeManager(ppSearchCrawlScopeManager);
|
|
pCatalogManager->Release();
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
HRESULT DisplayRootInfo(ISearchRoot* pSearchRoot)
|
|
{
|
|
PWSTR pszUrl = NULL;
|
|
HRESULT hr = pSearchRoot->get_RootURL(&pszUrl);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
wcout << L"\t" << pszUrl;
|
|
BOOL fProvidesNotifications = FALSE;
|
|
hr = pSearchRoot->get_ProvidesNotifications(&fProvidesNotifications);
|
|
if (SUCCEEDED(hr) && fProvidesNotifications)
|
|
{
|
|
wcout << L" - Provides Notifications";
|
|
}
|
|
CoTaskMemFree(pszUrl);
|
|
}
|
|
|
|
wcout << endl;
|
|
return hr;
|
|
}
|
|
|
|
int EnumRoots()
|
|
{
|
|
// Crawl scope manager for that catalog
|
|
ISearchCrawlScopeManager *pSearchCrawlScopeManager;
|
|
HRESULT hr = CreateCrawlScopManager(&pSearchCrawlScopeManager);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Search roots on that crawl scope
|
|
IEnumSearchRoots *pSearchRoots;
|
|
hr = pSearchCrawlScopeManager->EnumerateRoots(&pSearchRoots);
|
|
ISearchRoot *pSearchRoot;
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
while (SUCCEEDED(hr) &&
|
|
S_OK == (hr = pSearchRoots->Next(1, &pSearchRoot, NULL)))
|
|
{
|
|
hr = DisplayRootInfo(pSearchRoot);
|
|
pSearchRoot->Release();
|
|
}
|
|
pSearchRoots->Release();
|
|
}
|
|
pSearchCrawlScopeManager->Release();
|
|
}
|
|
|
|
return ReportHRESULTError(L"EnumRoots()", hr);
|
|
}
|
|
|
|
int AddRoots(PCWSTR pszURL)
|
|
{
|
|
wcout << L"Adding new root " << pszURL << endl;
|
|
|
|
// Crawl scope manager for that catalog
|
|
ISearchCatalogManager *pCatalogManager;
|
|
HRESULT hr = CreateCatalogManager(&pCatalogManager);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Crawl scope manager for that catalog
|
|
ISearchCrawlScopeManager *pSearchCrawlScopeManager;
|
|
hr = pCatalogManager->GetCrawlScopeManager(&pSearchCrawlScopeManager);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
ISearchRoot *pISearchRoot;
|
|
hr = CoCreateInstance(CLSID_CSearchRoot, NULL, CLSCTX_ALL, IID_PPV_ARGS(&pISearchRoot));
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pISearchRoot->put_RootURL(pszURL);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pSearchCrawlScopeManager->AddRoot(pISearchRoot);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pSearchCrawlScopeManager->SaveAll();
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pCatalogManager->ReindexSearchRoot(pszURL);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
wcout << "Reindexing was started for root " << pszURL << endl;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
pISearchRoot->Release();
|
|
}
|
|
pSearchCrawlScopeManager->Release();
|
|
}
|
|
pCatalogManager->Release();
|
|
}
|
|
|
|
return ReportHRESULTError(L"AddRoots()", hr);
|
|
}
|
|
|
|
int RemoveRoots(PCWSTR pszURL)
|
|
{
|
|
wcout << L"Removing root " << pszURL << endl;
|
|
|
|
// Crawl scope manager for that catalog
|
|
ISearchCrawlScopeManager *pSearchCrawlScopeManager;
|
|
HRESULT hr = CreateCrawlScopManager(&pSearchCrawlScopeManager);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pSearchCrawlScopeManager->RemoveRoot(pszURL);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pSearchCrawlScopeManager->SaveAll();
|
|
}
|
|
pSearchCrawlScopeManager->Release();
|
|
}
|
|
|
|
return ReportHRESULTError(L"AddRoots()", hr);
|
|
}
|
|
|
|
HRESULT DisplayRule(ISearchScopeRule* pSearchScopeRule)
|
|
{
|
|
PWSTR pszUrl;
|
|
HRESULT hr = pSearchScopeRule->get_PatternOrURL(&pszUrl);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
wcout << L"\t" << pszUrl;
|
|
BOOL fDefault = FALSE;
|
|
hr = pSearchScopeRule->get_IsDefault(&fDefault);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
wcout << (fDefault ? L" " : L" NOT ") << L"DEFAULT";
|
|
BOOL fIncluded = FALSE;
|
|
hr = pSearchScopeRule->get_IsIncluded(&fIncluded);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
wcout << (fIncluded ? L" INCLUDED" : L" EXCLUDED ");
|
|
}
|
|
}
|
|
CoTaskMemFree(pszUrl);
|
|
}
|
|
wcout << endl;
|
|
|
|
return hr;
|
|
}
|
|
|
|
int EnumRules()
|
|
{
|
|
// Crawl scope manager for that catalog
|
|
ISearchCrawlScopeManager *pSearchCrawlScopeManager;
|
|
HRESULT hr = CreateCrawlScopManager(&pSearchCrawlScopeManager);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Search roots on that crawl scope
|
|
IEnumSearchScopeRules *pScopeRules;
|
|
hr = pSearchCrawlScopeManager->EnumerateScopeRules(&pScopeRules);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
ISearchScopeRule *pSearchScopeRule;
|
|
while (SUCCEEDED(hr) &&
|
|
S_OK == (hr = pScopeRules->Next(1, &pSearchScopeRule, NULL)))
|
|
{
|
|
hr = DisplayRule(pSearchScopeRule);
|
|
pSearchScopeRule->Release();
|
|
}
|
|
pScopeRules->Release();
|
|
}
|
|
pSearchCrawlScopeManager->Release();
|
|
}
|
|
|
|
return ReportHRESULTError(L"EnumRules()", hr);
|
|
}
|
|
|
|
int AddRule(BOOL fDefault, BOOL fInclude, BOOL fOverride, PCWSTR pszURL)
|
|
{
|
|
wcout << L"Adding new " <<
|
|
(fDefault ? L"default " : L"user ") <<
|
|
(fInclude ? L"inclusion " : L"exclusion ") <<
|
|
"rule " << pszURL <<
|
|
((!fDefault && fOverride) ? L"overriding cildren rules" : L"" ) << endl;
|
|
|
|
// Crawl scope manager for that catalog
|
|
ISearchCrawlScopeManager *pSearchCrawlScopeManager;
|
|
HRESULT hr = CreateCrawlScopManager(&pSearchCrawlScopeManager);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (fDefault)
|
|
{
|
|
hr = pSearchCrawlScopeManager->AddDefaultScopeRule(pszURL, fInclude, FF_INDEXCOMPLEXURLS);
|
|
}
|
|
else
|
|
{
|
|
hr = pSearchCrawlScopeManager->AddUserScopeRule(pszURL,
|
|
fInclude,
|
|
fOverride,
|
|
FF_INDEXCOMPLEXURLS);
|
|
}
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pSearchCrawlScopeManager->SaveAll();
|
|
}
|
|
pSearchCrawlScopeManager->Release();
|
|
}
|
|
return ReportHRESULTError(L"AddRules()", hr);
|
|
}
|
|
|
|
int RemoveRule(BOOL fDefault, PCWSTR pszURL)
|
|
{
|
|
wcout << L"Removing " << (fDefault ? L"default" : L"user") << " rule " << pszURL << endl;
|
|
|
|
// Crawl scope manager for that catalog
|
|
ISearchCrawlScopeManager *pSearchCrawlScopeManager;
|
|
HRESULT hr = CreateCrawlScopManager(&pSearchCrawlScopeManager);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (fDefault)
|
|
{
|
|
hr = pSearchCrawlScopeManager->RemoveDefaultScopeRule(pszURL);
|
|
}
|
|
else
|
|
{
|
|
hr = pSearchCrawlScopeManager->RemoveScopeRule(pszURL);
|
|
}
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pSearchCrawlScopeManager->SaveAll();
|
|
}
|
|
pSearchCrawlScopeManager->Release();
|
|
}
|
|
return ReportHRESULTError(L"AddRules()", hr);
|
|
}
|
|
|
|
int Revert()
|
|
{
|
|
wcout << L"Reverting catalog to its default state." << endl;
|
|
|
|
// Crawl scope manager for that catalog
|
|
ISearchCrawlScopeManager *pSearchCrawlScopeManager;
|
|
HRESULT hr = CreateCrawlScopManager(&pSearchCrawlScopeManager);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pSearchCrawlScopeManager->RevertToDefaultScopes();
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pSearchCrawlScopeManager->SaveAll();
|
|
}
|
|
pSearchCrawlScopeManager->Release();
|
|
}
|
|
|
|
return ReportHRESULTError(L"Revert()", hr);
|
|
}
|
|
|
|
int Reset()
|
|
{
|
|
wcout << L"Resetting catalog." << endl;
|
|
|
|
ISearchCatalogManager *pCatalogManager;
|
|
HRESULT hr = CreateCatalogManager(&pCatalogManager);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pCatalogManager->Reset();
|
|
pCatalogManager->Release();
|
|
}
|
|
return ReportHRESULTError(L"Reset()", hr);
|
|
}
|
|
|
|
int Reindex()
|
|
{
|
|
wcout << L"Reindexing catalog." << endl;
|
|
|
|
ISearchCatalogManager *pCatalogManager;
|
|
HRESULT hr = CreateCatalogManager(&pCatalogManager);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pCatalogManager->Reindex();
|
|
pCatalogManager->Release();
|
|
}
|
|
return ReportHRESULTError(L"Reindex()", hr);
|
|
} |