Source code of Windows XP (NT5)
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.

541 lines
13 KiB

  1. /*++
  2. 1998 Seagate Software, Inc. All rights reserved.
  3. Module Name:
  4. hsmrlstk.cpp
  5. Abstract:
  6. This component represents the set of rules that are in effect for directory currently
  7. being scanned for one policy.
  8. Author:
  9. Chuck Bardeen [cbardeen] 29-Oct-1996
  10. Revision History:
  11. --*/
  12. #include "stdafx.h"
  13. #include "wsb.h"
  14. #include "job.h"
  15. #include "hsmrlstk.h"
  16. #define WSB_TRACE_IS WSB_TRACE_BIT_JOB
  17. HRESULT
  18. CHsmRuleStack::Do(
  19. IN IFsaScanItem* pScanItem
  20. )
  21. /*++
  22. Implements:
  23. IHsmRuleStack::Do().
  24. --*/
  25. {
  26. HRESULT hr = S_OK;
  27. WsbTraceIn(OLESTR("CHsmRuleStack::Do"), OLESTR(""));
  28. try {
  29. WsbAssert(0 != pScanItem, E_POINTER);
  30. WsbAssert(m_pAction != 0, E_UNEXPECTED);
  31. WsbAffirmHr(m_pAction->Do(pScanItem));
  32. } WsbCatch(hr);
  33. WsbTraceOut(OLESTR("CHsmRuleStack::Do"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  34. return(hr);
  35. }
  36. HRESULT
  37. CHsmRuleStack::DoesMatch(
  38. IN IFsaScanItem* pScanItem,
  39. OUT BOOL* pShouldDo
  40. )
  41. /*++
  42. Implements:
  43. IHsmRuleStack::DoesMatch().
  44. --*/
  45. {
  46. HRESULT hr = S_OK;
  47. HRESULT hrNameMatch = S_OK; // Used for event logging only
  48. CComPtr<IWsbEnum> pEnumCriteria;
  49. CComPtr<IHsmRule> pRule;
  50. CComPtr<IHsmCriteria> pCriteria;
  51. BOOL isMatched = FALSE;
  52. BOOL ruleMatched = FALSE; // Used for event logging only
  53. BOOL shouldCheck;
  54. CWsbStringPtr name;
  55. CWsbStringPtr path;
  56. CWsbStringPtr rulePath;
  57. BOOL shouldDo = FALSE;
  58. WsbTraceIn(OLESTR("CHsmRuleStack::DoesMatch"), OLESTR(""));
  59. try {
  60. WsbAssert(0 != pScanItem, E_POINTER);
  61. WsbAssert(0 != pShouldDo, E_POINTER);
  62. *pShouldDo = FALSE;
  63. // NOTE: The matching code starts at the bottom of the list and looks for
  64. // the first rule that matches. This makes it important how the list is organized.
  65. // Currently, the Push() method does not make any attempts to organize the list, so
  66. // it is up to whoever configure the rules in the policy definition to have it
  67. // organized properly. A proper order within a directory would be to have the specific
  68. // rules (i.e. no wildcards) after the wildcard rules (i.e. specific searched first).
  69. // Start we the last rule in the collection, and search upwards until a
  70. // rule is found that matches or all rules have been checked.
  71. WsbAffirmHr(pScanItem->GetName(&name, 0));
  72. hr = m_pEnumStackRules->Last(IID_IHsmRule, (void**) &pRule);
  73. while (SUCCEEDED(hr) && !isMatched) {
  74. try {
  75. shouldCheck = TRUE;
  76. // If the rule only applies to the directory it was defined in, then make
  77. // sure that the item is from that directory.
  78. if (pRule->IsUsedInSubDirs() == S_FALSE) {
  79. // Unfortunately, these two paths differ by an appended \ when they
  80. // are otherwise the same, so make them the same.
  81. WsbAffirmHr(pScanItem->GetPath(&path, 0));
  82. if ((wcslen(path) > 1) && (path[(int) (wcslen(path) - 1)] == L'\\')) {
  83. path[(int) (wcslen(path) - 1)] = 0;
  84. }
  85. rulePath.Free();
  86. WsbAffirmHr(pRule->GetPath(&rulePath, 0));
  87. if ((wcslen(rulePath) > 1) && (rulePath[(int) (wcslen(rulePath) - 1)] == L'\\')) {
  88. rulePath[(int) (wcslen(rulePath) - 1)] = 0;
  89. }
  90. if (_wcsicmp(path, rulePath) != 0) {
  91. shouldCheck = FALSE;
  92. }
  93. }
  94. if (shouldCheck) {
  95. // Does the name of the rule match the name of the file?
  96. hrNameMatch = pRule->MatchesName(name);
  97. WsbAffirmHrOk(hrNameMatch);
  98. ruleMatched = TRUE;
  99. // Do the criteria match the attributes of the file?
  100. isMatched = TRUE;
  101. pEnumCriteria = 0;
  102. WsbAffirmHr(pRule->EnumCriteria(&pEnumCriteria));
  103. pCriteria = 0;
  104. WsbAffirmHr(pEnumCriteria->First(IID_IHsmCriteria, (void**) &pCriteria));
  105. while (isMatched) {
  106. HRESULT hrShouldDo;
  107. hrShouldDo = pCriteria->ShouldDo(pScanItem, m_scale);
  108. if (S_FALSE == hrShouldDo) {
  109. isMatched = FALSE;
  110. } else if (S_OK == hrShouldDo) {
  111. pCriteria = 0;
  112. WsbAffirmHr(pEnumCriteria->Next(IID_IHsmCriteria, (void**) &pCriteria));
  113. } else {
  114. WsbThrow(hrShouldDo);
  115. }
  116. }
  117. }
  118. } WsbCatchAndDo(hr, if (WSB_E_NOTFOUND == hr) {hr = S_OK;} else {isMatched = FALSE;});
  119. // If it didn't match, then try the next rule.
  120. if (SUCCEEDED(hr) && !isMatched) {
  121. pRule = 0;
  122. WsbAffirmHr(m_pEnumStackRules->Previous(IID_IHsmRule, (void**) &pRule));
  123. }
  124. }
  125. // Include rules mean that we should do the operation and exclude rules
  126. // mean that we should not.
  127. if (SUCCEEDED(hr)) {
  128. if (isMatched) {
  129. hr = S_OK;
  130. if (pRule->IsInclude() == S_OK) {
  131. shouldDo = TRUE;
  132. }
  133. } else {
  134. hr = S_FALSE;
  135. }
  136. }
  137. if ((FALSE == shouldDo) && (FALSE == ruleMatched)) {
  138. //
  139. // Log that we skipped the file because it didn't
  140. // match a rule
  141. //
  142. CWsbStringPtr jobName;
  143. CWsbStringPtr fileName;
  144. CComPtr<IHsmSession> pSession;
  145. pScanItem->GetFullPathAndName( 0, 0, &fileName, 0);
  146. pScanItem->GetSession(&pSession);
  147. pSession->GetName(&jobName, 0);
  148. WsbLogEvent(JOB_MESSAGE_SCAN_FILESKIPPED_NORULE, 0, NULL, (OLECHAR *)jobName, WsbAbbreviatePath(fileName, 120), WsbHrAsString(hrNameMatch), NULL);
  149. }
  150. *pShouldDo = shouldDo;
  151. } WsbCatchAndDo(hr, if (WSB_E_NOTFOUND == hr) {hr = S_FALSE;});
  152. WsbTraceOut(OLESTR("CHsmRuleStack::DoesMatch"), OLESTR("hr = <%ls>, shouldDo = <%ls>"), WsbHrAsString(hr), WsbBoolAsString(shouldDo));
  153. return(hr);
  154. }
  155. HRESULT
  156. CHsmRuleStack::FinalConstruct(
  157. void
  158. )
  159. /*++
  160. Implements:
  161. CComObjectRoot::FinalConstruct().
  162. --*/
  163. {
  164. HRESULT hr = S_OK;
  165. try {
  166. WsbAffirmHr(CWsbObject::FinalConstruct());
  167. m_scale = HSM_JOBSCALE_100;
  168. m_usesDefaults = TRUE;
  169. //Create the criteria collection.
  170. WsbAffirmHr(CoCreateInstance(CLSID_CWsbOrderedCollection, NULL, CLSCTX_ALL, IID_IWsbCollection, (void**) &m_pRules));
  171. WsbAffirmHr(m_pRules->Enum(&m_pEnumStackRules));
  172. } WsbCatch(hr);
  173. return(hr);
  174. }
  175. HRESULT
  176. CHsmRuleStack::GetClassID(
  177. OUT CLSID* pClsid
  178. )
  179. /*++
  180. Implements:
  181. IPersist::GetClassID().
  182. --*/
  183. {
  184. HRESULT hr = S_OK;
  185. WsbTraceIn(OLESTR("CHsmRuleStack::GetClassID"), OLESTR(""));
  186. try {
  187. WsbAssert(0 != pClsid, E_POINTER);
  188. *pClsid = CLSID_CHsmRuleStack;
  189. } WsbCatch(hr);
  190. WsbTraceOut(OLESTR("CHsmRuleStack::GetClassID"), OLESTR("hr = <%ls>, CLSID = <%ls>"), WsbHrAsString(hr), WsbGuidAsString(*pClsid));
  191. return(hr);
  192. }
  193. HRESULT
  194. CHsmRuleStack::GetSizeMax(
  195. OUT ULARGE_INTEGER* pSize
  196. )
  197. /*++
  198. Implements:
  199. IPersistStream::GetSizeMax().
  200. --*/
  201. {
  202. HRESULT hr = E_NOTIMPL;
  203. WsbTraceIn(OLESTR("CHsmRuleStack::GetSizeMax"), OLESTR(""));
  204. WsbTraceOut(OLESTR("CHsmRuleStack::GetSizeMax"), OLESTR("hr = <%ls>, Size = <%ls>"), WsbHrAsString(hr), WsbPtrToUliAsString(pSize));
  205. return(hr);
  206. }
  207. HRESULT
  208. CHsmRuleStack::Init(
  209. IN IHsmPolicy* pPolicy,
  210. IN IFsaResource* pResource
  211. )
  212. /*++
  213. Implements:
  214. IHsmRuleStack::Init().
  215. --*/
  216. {
  217. HRESULT hr = S_OK;
  218. try {
  219. WsbAssert(0 != pPolicy, E_POINTER);
  220. WsbAffirmHr(pPolicy->GetScale(&m_scale));
  221. WsbAffirmHr(pPolicy->GetAction(&m_pAction));
  222. WsbAffirmHr(pPolicy->EnumRules(&m_pEnumPolicyRules));
  223. if (pPolicy->UsesDefaultRules() == S_OK) {
  224. m_usesDefaults = TRUE;
  225. } else {
  226. m_usesDefaults = FALSE;
  227. }
  228. m_pPolicy = pPolicy;
  229. WsbAffirmHr(pResource->EnumDefaultRules(&m_pEnumDefaultRules));
  230. } WsbCatch(hr);
  231. return(hr);
  232. }
  233. HRESULT
  234. CHsmRuleStack::Load(
  235. IN IStream* /*pStream*/
  236. )
  237. /*++
  238. Implements:
  239. IPersistStream::Load().
  240. --*/
  241. {
  242. HRESULT hr = E_NOTIMPL;
  243. WsbTraceIn(OLESTR("CHsmRuleStack::Load"), OLESTR(""));
  244. WsbTraceOut(OLESTR("CHsmRuleStack::Load"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  245. return(hr);
  246. }
  247. HRESULT
  248. CHsmRuleStack::Pop(
  249. IN OLECHAR* path
  250. )
  251. /*++
  252. Implements:
  253. IHsmRuleStack::Pop().
  254. --*/
  255. {
  256. HRESULT hr = S_OK;
  257. CWsbStringPtr rulePath;
  258. CComPtr<IHsmRule> pRule;
  259. WsbTraceIn(OLESTR("CHsmRuleStack::Pop"), OLESTR(""));
  260. try {
  261. WsbAssert(0 != path, E_POINTER);
  262. // Starting at the end of the list, remove any rules that have the same
  263. // path as the one specified.
  264. WsbAffirmHr(m_pEnumStackRules->Last(IID_IHsmRule, (void**) &pRule));
  265. WsbAffirmHr(pRule->GetPath(&rulePath, 0));
  266. while(_wcsicmp(path, rulePath) == 0) {
  267. WsbAffirmHr(m_pRules->RemoveAndRelease(pRule));
  268. pRule = 0;
  269. WsbAffirmHr(m_pEnumStackRules->Last(IID_IHsmRule, (void**) &pRule));
  270. rulePath.Free();
  271. WsbAffirmHr(pRule->GetPath(&rulePath, 0));
  272. }
  273. } WsbCatchAndDo(hr, if (WSB_E_NOTFOUND == hr) {hr = S_OK;});
  274. WsbTraceOut(OLESTR("CHsmRuleStack::Pop"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  275. return(hr);
  276. }
  277. HRESULT
  278. CHsmRuleStack::Push(
  279. IN OLECHAR* path
  280. )
  281. /*++
  282. Implements:
  283. IHsmRuleStack::Push().
  284. --*/
  285. {
  286. HRESULT hr = S_OK;
  287. CWsbStringPtr rulePath;
  288. CComPtr<IHsmRule> pRule;
  289. CComPtr<IWsbIndexedCollection> pCollection;
  290. WsbTraceIn(OLESTR("CHsmRuleStack::Push"), OLESTR(""));
  291. try {
  292. WsbAssert(0 != path, E_POINTER);
  293. // We need to preserve the order of the rules, so use the indexed collection interface.
  294. WsbAffirmHr(m_pRules->QueryInterface(IID_IWsbIndexedCollection, (void**) &pCollection));
  295. // Add any policy rules for this directory to the stack.
  296. //
  297. // NOTE: We may want to add some code to check for exclusion rules of the
  298. // entire directory (with no subdirectory inclusions and return the
  299. // JOB_E_DIREXCLUDED error to skip scanning of the directory.
  300. //
  301. // NOTE: It might be nice if the policy rules were a sorted collection to
  302. // speed up processing.
  303. hr = m_pEnumPolicyRules->First(IID_IHsmRule, (void**) &pRule);
  304. while (SUCCEEDED(hr)) {
  305. rulePath.Free();
  306. WsbAffirmHr(pRule->GetPath(&rulePath, 0));
  307. if (_wcsicmp(path, rulePath) == 0) {
  308. WsbAffirmHr(pCollection->Append(pRule));
  309. WsbTrace(OLESTR("CHsmRuleStack::Push - Using policy rule <%ls>.\n"), (OLECHAR *)rulePath);
  310. }
  311. pRule = 0;
  312. hr = m_pEnumPolicyRules->Next(IID_IHsmRule, (void**) &pRule);
  313. }
  314. if (WSB_E_NOTFOUND == hr) {
  315. hr = S_OK;
  316. }
  317. // Add any default rules for this directory to the stack.
  318. if (m_usesDefaults) {
  319. hr = m_pEnumDefaultRules->First(IID_IHsmRule, (void**) &pRule);
  320. while (SUCCEEDED(hr)) {
  321. rulePath.Free();
  322. WsbAffirmHr(pRule->GetPath(&rulePath, 0));
  323. if (_wcsicmp(path, rulePath) == 0) {
  324. WsbAffirmHr(pCollection->Append(pRule));
  325. WsbTrace(OLESTR("CHsmRuleStack::Push -- Using default rule <%ls>.\n"), (OLECHAR *)rulePath);
  326. }
  327. pRule = 0;
  328. hr = m_pEnumDefaultRules->Next(IID_IHsmRule, (void**) &pRule);
  329. }
  330. } else {
  331. WsbTrace(OLESTR("CHsmRuleStack::Push -- Not using default rules.\n"));
  332. }
  333. if (WSB_E_NOTFOUND == hr) {
  334. hr = S_OK;
  335. }
  336. } WsbCatch(hr);
  337. WsbTraceOut(OLESTR("CHsmRuleStack::Push"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  338. return(hr);
  339. }
  340. HRESULT
  341. CHsmRuleStack::Save(
  342. IN IStream* /*pStream*/,
  343. IN BOOL clearDirty
  344. )
  345. /*++
  346. Implements:
  347. IPersistStream::Save().
  348. --*/
  349. {
  350. HRESULT hr = E_NOTIMPL;
  351. WsbTraceIn(OLESTR("CHsmRuleStack::Save"), OLESTR("clearDirty = <%ls>"), WsbBoolAsString(clearDirty));
  352. WsbTraceOut(OLESTR("CHsmRuleStack::Save"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
  353. return(hr);
  354. }
  355. HRESULT
  356. CHsmRuleStack::Test(
  357. USHORT* passed,
  358. USHORT* failed
  359. )
  360. /*++
  361. Implements:
  362. IWsbTestable::Test().
  363. --*/
  364. {
  365. HRESULT hr = S_OK;
  366. try {
  367. WsbAssert(0 != passed, E_POINTER);
  368. WsbAssert(0 != failed, E_POINTER);
  369. *passed = 0;
  370. *failed = 0;
  371. } WsbCatch(hr);
  372. return(hr);
  373. }