windows-nt/Source/XPSP1/NT/base/fs/hsm/job/hsmrlstk.cpp
2020-09-26 16:20:57 +08:00

542 lines
13 KiB
C++
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
© 1998 Seagate Software, Inc. All rights reserved.
Module Name:
hsmrlstk.cpp
Abstract:
This component represents the set of rules that are in effect for directory currently
being scanned for one policy.
Author:
Chuck Bardeen [cbardeen] 29-Oct-1996
Revision History:
--*/
#include "stdafx.h"
#include "wsb.h"
#include "job.h"
#include "hsmrlstk.h"
#define WSB_TRACE_IS WSB_TRACE_BIT_JOB
HRESULT
CHsmRuleStack::Do(
IN IFsaScanItem* pScanItem
)
/*++
Implements:
IHsmRuleStack::Do().
--*/
{
HRESULT hr = S_OK;
WsbTraceIn(OLESTR("CHsmRuleStack::Do"), OLESTR(""));
try {
WsbAssert(0 != pScanItem, E_POINTER);
WsbAssert(m_pAction != 0, E_UNEXPECTED);
WsbAffirmHr(m_pAction->Do(pScanItem));
} WsbCatch(hr);
WsbTraceOut(OLESTR("CHsmRuleStack::Do"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return(hr);
}
HRESULT
CHsmRuleStack::DoesMatch(
IN IFsaScanItem* pScanItem,
OUT BOOL* pShouldDo
)
/*++
Implements:
IHsmRuleStack::DoesMatch().
--*/
{
HRESULT hr = S_OK;
HRESULT hrNameMatch = S_OK; // Used for event logging only
CComPtr<IWsbEnum> pEnumCriteria;
CComPtr<IHsmRule> pRule;
CComPtr<IHsmCriteria> pCriteria;
BOOL isMatched = FALSE;
BOOL ruleMatched = FALSE; // Used for event logging only
BOOL shouldCheck;
CWsbStringPtr name;
CWsbStringPtr path;
CWsbStringPtr rulePath;
BOOL shouldDo = FALSE;
WsbTraceIn(OLESTR("CHsmRuleStack::DoesMatch"), OLESTR(""));
try {
WsbAssert(0 != pScanItem, E_POINTER);
WsbAssert(0 != pShouldDo, E_POINTER);
*pShouldDo = FALSE;
// NOTE: The matching code starts at the bottom of the list and looks for
// the first rule that matches. This makes it important how the list is organized.
// Currently, the Push() method does not make any attempts to organize the list, so
// it is up to whoever configure the rules in the policy definition to have it
// organized properly. A proper order within a directory would be to have the specific
// rules (i.e. no wildcards) after the wildcard rules (i.e. specific searched first).
// Start we the last rule in the collection, and search upwards until a
// rule is found that matches or all rules have been checked.
WsbAffirmHr(pScanItem->GetName(&name, 0));
hr = m_pEnumStackRules->Last(IID_IHsmRule, (void**) &pRule);
while (SUCCEEDED(hr) && !isMatched) {
try {
shouldCheck = TRUE;
// If the rule only applies to the directory it was defined in, then make
// sure that the item is from that directory.
if (pRule->IsUsedInSubDirs() == S_FALSE) {
// Unfortunately, these two paths differ by an appended \ when they
// are otherwise the same, so make them the same.
WsbAffirmHr(pScanItem->GetPath(&path, 0));
if ((wcslen(path) > 1) && (path[(int) (wcslen(path) - 1)] == L'\\')) {
path[(int) (wcslen(path) - 1)] = 0;
}
rulePath.Free();
WsbAffirmHr(pRule->GetPath(&rulePath, 0));
if ((wcslen(rulePath) > 1) && (rulePath[(int) (wcslen(rulePath) - 1)] == L'\\')) {
rulePath[(int) (wcslen(rulePath) - 1)] = 0;
}
if (_wcsicmp(path, rulePath) != 0) {
shouldCheck = FALSE;
}
}
if (shouldCheck) {
// Does the name of the rule match the name of the file?
hrNameMatch = pRule->MatchesName(name);
WsbAffirmHrOk(hrNameMatch);
ruleMatched = TRUE;
// Do the criteria match the attributes of the file?
isMatched = TRUE;
pEnumCriteria = 0;
WsbAffirmHr(pRule->EnumCriteria(&pEnumCriteria));
pCriteria = 0;
WsbAffirmHr(pEnumCriteria->First(IID_IHsmCriteria, (void**) &pCriteria));
while (isMatched) {
HRESULT hrShouldDo;
hrShouldDo = pCriteria->ShouldDo(pScanItem, m_scale);
if (S_FALSE == hrShouldDo) {
isMatched = FALSE;
} else if (S_OK == hrShouldDo) {
pCriteria = 0;
WsbAffirmHr(pEnumCriteria->Next(IID_IHsmCriteria, (void**) &pCriteria));
} else {
WsbThrow(hrShouldDo);
}
}
}
} WsbCatchAndDo(hr, if (WSB_E_NOTFOUND == hr) {hr = S_OK;} else {isMatched = FALSE;});
// If it didn't match, then try the next rule.
if (SUCCEEDED(hr) && !isMatched) {
pRule = 0;
WsbAffirmHr(m_pEnumStackRules->Previous(IID_IHsmRule, (void**) &pRule));
}
}
// Include rules mean that we should do the operation and exclude rules
// mean that we should not.
if (SUCCEEDED(hr)) {
if (isMatched) {
hr = S_OK;
if (pRule->IsInclude() == S_OK) {
shouldDo = TRUE;
}
} else {
hr = S_FALSE;
}
}
if ((FALSE == shouldDo) && (FALSE == ruleMatched)) {
//
// Log that we skipped the file because it didn't
// match a rule
//
CWsbStringPtr jobName;
CWsbStringPtr fileName;
CComPtr<IHsmSession> pSession;
pScanItem->GetFullPathAndName( 0, 0, &fileName, 0);
pScanItem->GetSession(&pSession);
pSession->GetName(&jobName, 0);
WsbLogEvent(JOB_MESSAGE_SCAN_FILESKIPPED_NORULE, 0, NULL, (OLECHAR *)jobName, WsbAbbreviatePath(fileName, 120), WsbHrAsString(hrNameMatch), NULL);
}
*pShouldDo = shouldDo;
} WsbCatchAndDo(hr, if (WSB_E_NOTFOUND == hr) {hr = S_FALSE;});
WsbTraceOut(OLESTR("CHsmRuleStack::DoesMatch"), OLESTR("hr = <%ls>, shouldDo = <%ls>"), WsbHrAsString(hr), WsbBoolAsString(shouldDo));
return(hr);
}
HRESULT
CHsmRuleStack::FinalConstruct(
void
)
/*++
Implements:
CComObjectRoot::FinalConstruct().
--*/
{
HRESULT hr = S_OK;
try {
WsbAffirmHr(CWsbObject::FinalConstruct());
m_scale = HSM_JOBSCALE_100;
m_usesDefaults = TRUE;
//Create the criteria collection.
WsbAffirmHr(CoCreateInstance(CLSID_CWsbOrderedCollection, NULL, CLSCTX_ALL, IID_IWsbCollection, (void**) &m_pRules));
WsbAffirmHr(m_pRules->Enum(&m_pEnumStackRules));
} WsbCatch(hr);
return(hr);
}
HRESULT
CHsmRuleStack::GetClassID(
OUT CLSID* pClsid
)
/*++
Implements:
IPersist::GetClassID().
--*/
{
HRESULT hr = S_OK;
WsbTraceIn(OLESTR("CHsmRuleStack::GetClassID"), OLESTR(""));
try {
WsbAssert(0 != pClsid, E_POINTER);
*pClsid = CLSID_CHsmRuleStack;
} WsbCatch(hr);
WsbTraceOut(OLESTR("CHsmRuleStack::GetClassID"), OLESTR("hr = <%ls>, CLSID = <%ls>"), WsbHrAsString(hr), WsbGuidAsString(*pClsid));
return(hr);
}
HRESULT
CHsmRuleStack::GetSizeMax(
OUT ULARGE_INTEGER* pSize
)
/*++
Implements:
IPersistStream::GetSizeMax().
--*/
{
HRESULT hr = E_NOTIMPL;
WsbTraceIn(OLESTR("CHsmRuleStack::GetSizeMax"), OLESTR(""));
WsbTraceOut(OLESTR("CHsmRuleStack::GetSizeMax"), OLESTR("hr = <%ls>, Size = <%ls>"), WsbHrAsString(hr), WsbPtrToUliAsString(pSize));
return(hr);
}
HRESULT
CHsmRuleStack::Init(
IN IHsmPolicy* pPolicy,
IN IFsaResource* pResource
)
/*++
Implements:
IHsmRuleStack::Init().
--*/
{
HRESULT hr = S_OK;
try {
WsbAssert(0 != pPolicy, E_POINTER);
WsbAffirmHr(pPolicy->GetScale(&m_scale));
WsbAffirmHr(pPolicy->GetAction(&m_pAction));
WsbAffirmHr(pPolicy->EnumRules(&m_pEnumPolicyRules));
if (pPolicy->UsesDefaultRules() == S_OK) {
m_usesDefaults = TRUE;
} else {
m_usesDefaults = FALSE;
}
m_pPolicy = pPolicy;
WsbAffirmHr(pResource->EnumDefaultRules(&m_pEnumDefaultRules));
} WsbCatch(hr);
return(hr);
}
HRESULT
CHsmRuleStack::Load(
IN IStream* /*pStream*/
)
/*++
Implements:
IPersistStream::Load().
--*/
{
HRESULT hr = E_NOTIMPL;
WsbTraceIn(OLESTR("CHsmRuleStack::Load"), OLESTR(""));
WsbTraceOut(OLESTR("CHsmRuleStack::Load"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return(hr);
}
HRESULT
CHsmRuleStack::Pop(
IN OLECHAR* path
)
/*++
Implements:
IHsmRuleStack::Pop().
--*/
{
HRESULT hr = S_OK;
CWsbStringPtr rulePath;
CComPtr<IHsmRule> pRule;
WsbTraceIn(OLESTR("CHsmRuleStack::Pop"), OLESTR(""));
try {
WsbAssert(0 != path, E_POINTER);
// Starting at the end of the list, remove any rules that have the same
// path as the one specified.
WsbAffirmHr(m_pEnumStackRules->Last(IID_IHsmRule, (void**) &pRule));
WsbAffirmHr(pRule->GetPath(&rulePath, 0));
while(_wcsicmp(path, rulePath) == 0) {
WsbAffirmHr(m_pRules->RemoveAndRelease(pRule));
pRule = 0;
WsbAffirmHr(m_pEnumStackRules->Last(IID_IHsmRule, (void**) &pRule));
rulePath.Free();
WsbAffirmHr(pRule->GetPath(&rulePath, 0));
}
} WsbCatchAndDo(hr, if (WSB_E_NOTFOUND == hr) {hr = S_OK;});
WsbTraceOut(OLESTR("CHsmRuleStack::Pop"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return(hr);
}
HRESULT
CHsmRuleStack::Push(
IN OLECHAR* path
)
/*++
Implements:
IHsmRuleStack::Push().
--*/
{
HRESULT hr = S_OK;
CWsbStringPtr rulePath;
CComPtr<IHsmRule> pRule;
CComPtr<IWsbIndexedCollection> pCollection;
WsbTraceIn(OLESTR("CHsmRuleStack::Push"), OLESTR(""));
try {
WsbAssert(0 != path, E_POINTER);
// We need to preserve the order of the rules, so use the indexed collection interface.
WsbAffirmHr(m_pRules->QueryInterface(IID_IWsbIndexedCollection, (void**) &pCollection));
// Add any policy rules for this directory to the stack.
//
// NOTE: We may want to add some code to check for exclusion rules of the
// entire directory (with no subdirectory inclusions and return the
// JOB_E_DIREXCLUDED error to skip scanning of the directory.
//
// NOTE: It might be nice if the policy rules were a sorted collection to
// speed up processing.
hr = m_pEnumPolicyRules->First(IID_IHsmRule, (void**) &pRule);
while (SUCCEEDED(hr)) {
rulePath.Free();
WsbAffirmHr(pRule->GetPath(&rulePath, 0));
if (_wcsicmp(path, rulePath) == 0) {
WsbAffirmHr(pCollection->Append(pRule));
WsbTrace(OLESTR("CHsmRuleStack::Push - Using policy rule <%ls>.\n"), (OLECHAR *)rulePath);
}
pRule = 0;
hr = m_pEnumPolicyRules->Next(IID_IHsmRule, (void**) &pRule);
}
if (WSB_E_NOTFOUND == hr) {
hr = S_OK;
}
// Add any default rules for this directory to the stack.
if (m_usesDefaults) {
hr = m_pEnumDefaultRules->First(IID_IHsmRule, (void**) &pRule);
while (SUCCEEDED(hr)) {
rulePath.Free();
WsbAffirmHr(pRule->GetPath(&rulePath, 0));
if (_wcsicmp(path, rulePath) == 0) {
WsbAffirmHr(pCollection->Append(pRule));
WsbTrace(OLESTR("CHsmRuleStack::Push -- Using default rule <%ls>.\n"), (OLECHAR *)rulePath);
}
pRule = 0;
hr = m_pEnumDefaultRules->Next(IID_IHsmRule, (void**) &pRule);
}
} else {
WsbTrace(OLESTR("CHsmRuleStack::Push -- Not using default rules.\n"));
}
if (WSB_E_NOTFOUND == hr) {
hr = S_OK;
}
} WsbCatch(hr);
WsbTraceOut(OLESTR("CHsmRuleStack::Push"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return(hr);
}
HRESULT
CHsmRuleStack::Save(
IN IStream* /*pStream*/,
IN BOOL clearDirty
)
/*++
Implements:
IPersistStream::Save().
--*/
{
HRESULT hr = E_NOTIMPL;
WsbTraceIn(OLESTR("CHsmRuleStack::Save"), OLESTR("clearDirty = <%ls>"), WsbBoolAsString(clearDirty));
WsbTraceOut(OLESTR("CHsmRuleStack::Save"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return(hr);
}
HRESULT
CHsmRuleStack::Test(
USHORT* passed,
USHORT* failed
)
/*++
Implements:
IWsbTestable::Test().
--*/
{
HRESULT hr = S_OK;
try {
WsbAssert(0 != passed, E_POINTER);
WsbAssert(0 != failed, E_POINTER);
*passed = 0;
*failed = 0;
} WsbCatch(hr);
return(hr);
}