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.

194 lines
4.7 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1998, Microsoft Corp. All rights reserved.
  4. //
  5. // FILE
  6. //
  7. // Match.cpp
  8. //
  9. // SYNOPSIS
  10. //
  11. // This file defines the class AttributeMatch.
  12. //
  13. // MODIFICATION HISTORY
  14. //
  15. // 02/04/1998 Original version.
  16. // 03/18/1998 Treat IASTYPE_ENUM as an Integer.
  17. // 04/06/1998 Use the IASAttributeArray class so we can handle a large
  18. // number of attributes.
  19. // 08/10/1998 Use dictionary directly.
  20. // 03/23/1999 Renamed Match to AttributeMatch.
  21. // 04/05/1999 Need custom UpdateRegistry method.
  22. // 04/17/2000 Port to new dictionary API.
  23. //
  24. ///////////////////////////////////////////////////////////////////////////////
  25. #include <ias.h>
  26. #include <iastlb.h>
  27. #include <iastlutl.h>
  28. #include <iasutil.h>
  29. #include <factory.h>
  30. #include <match.h>
  31. #include <memory>
  32. HRESULT AttributeMatch::UpdateRegistry(BOOL bRegister) throw ()
  33. {
  34. // We can't use the IAS_DECLARE_REGISTRY macro because our ProgID doesn't
  35. // match the implementation class.
  36. return IASRegisterComponent(
  37. _Module.GetModuleInstance(),
  38. __uuidof(AttributeMatch),
  39. IASProgramName,
  40. L"Match",
  41. IAS_REGISTRY_INPROC | IAS_REGISTRY_FREE,
  42. __uuidof(NetworkPolicy),
  43. 1,
  44. 0,
  45. bRegister
  46. );
  47. }
  48. BOOL AttributeMatch::checkAttribute(PIASATTRIBUTE attr) const throw ()
  49. {
  50. _ASSERT(attr != NULL);
  51. switch (attr->Value.itType)
  52. {
  53. case IASTYPE_ENUM:
  54. case IASTYPE_INTEGER:
  55. {
  56. WCHAR wsz[11] = L"";
  57. return regex.testString(_ultow(attr->Value.Integer, wsz, 10));
  58. }
  59. case IASTYPE_INET_ADDR:
  60. {
  61. WCHAR wsz[16];
  62. return regex.testString(ias_inet_htow(attr->Value.InetAddr, wsz));
  63. }
  64. case IASTYPE_STRING:
  65. {
  66. IASAttributeUnicodeAlloc(attr);
  67. return regex.testString(attr->Value.String.pszWide);
  68. }
  69. case IASTYPE_OCTET_STRING:
  70. case IASTYPE_PROV_SPECIFIC:
  71. {
  72. PWSTR wsz = IAS_OCT2WIDE(attr->Value.OctetString);
  73. return regex.testString(wsz);
  74. }
  75. }
  76. return false;
  77. }
  78. STDMETHODIMP AttributeMatch::IsTrue(IRequest* pRequest, VARIANT_BOOL *pVal)
  79. {
  80. _ASSERT(pRequest != NULL);
  81. _ASSERT(pVal != NULL);
  82. _ASSERT(dfa != NULL);
  83. *pVal = VARIANT_FALSE;
  84. try
  85. {
  86. //////////
  87. // Retrieve the relevant attributes.
  88. //////////
  89. IASTL::IASRequest request(pRequest);
  90. IASTL::IASAttributeVectorWithBuffer<8> attrs;
  91. attrs.load(request, targetID);
  92. //////////
  93. // Look for a match.
  94. //////////
  95. IASTL::IASAttributeVector::iterator it;
  96. for (it = attrs.begin(); it != attrs.end(); ++it)
  97. {
  98. if (checkAttribute(it->pAttribute))
  99. {
  100. *pVal = VARIANT_TRUE;
  101. break;
  102. }
  103. }
  104. }
  105. CATCH_AND_RETURN()
  106. return S_OK;
  107. }
  108. STDMETHODIMP AttributeMatch::put_ConditionText(BSTR newVal)
  109. {
  110. if (newVal == NULL) { return E_INVALIDARG; }
  111. //////////
  112. // Make a local copy so we can modify it.
  113. //////////
  114. size_t len = sizeof(WCHAR) * (wcslen(newVal) + 1);
  115. PWSTR attrName = (PWSTR)memcpy(_alloca(len), newVal, len);
  116. //////////
  117. // Split into attribute name and regular expression: "<attrName>=<regex>"
  118. //////////
  119. PWSTR pattern = wcschr(attrName, L'=');
  120. if (pattern == NULL) { return E_INVALIDARG; }
  121. *pattern++ = '\0';
  122. HRESULT hr;
  123. DWORD attrID;
  124. try
  125. {
  126. // Names of various columns in the dictionary.
  127. const PCWSTR COLUMNS[] = { L"Name", L"ID", NULL };
  128. // Get the dictionary.
  129. IASTL::IASDictionary dnary(COLUMNS);
  130. // Lookup the target attribute in the dictionary.
  131. do
  132. {
  133. if (!dnary.next()) { return E_INVALIDARG; }
  134. if (_wcsicmp(dnary.getBSTR(0), attrName) == 0)
  135. {
  136. attrID = (DWORD)dnary.getLong(1);
  137. break;
  138. }
  139. } while (true);
  140. }
  141. catch (const _com_error& ce)
  142. {
  143. return ce.Error();
  144. }
  145. // Create a new RegularExpression.
  146. RegularExpression tmp;
  147. hr = tmp.setGlobal(TRUE);
  148. if (FAILED(hr)) { return hr; }
  149. hr = tmp.setIgnoreCase(TRUE);
  150. if (FAILED(hr)) { return hr; }
  151. hr = tmp.setPattern(pattern);
  152. if (FAILED(hr)) { return hr; }
  153. // Store the condition text.
  154. hr = Condition::put_ConditionText(newVal);
  155. if (FAILED(hr)) { return hr; }
  156. // Everything succeeded, so save the results.
  157. targetID = attrID;
  158. regex.swap(tmp);
  159. return S_OK;
  160. }