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.

392 lines
9.3 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. /*++
  3. Copyright (C) Microsoft Corporation, 1998 - 1999
  4. Module Name:
  5. IASStringEditorPage.cpp
  6. Abstract:
  7. Implementation file for the CIASPgSingleAttr class.
  8. Revision History:
  9. mmaguire 06/25/98 - revised Baogang Yao's original implementation
  10. --*/
  11. //////////////////////////////////////////////////////////////////////////////
  12. //////////////////////////////////////////////////////////////////////////////
  13. // BEGIN INCLUDES
  14. //
  15. // standard includes:
  16. //
  17. #include "Precompiled.h"
  18. //
  19. // where we can find declaration for main class in this file:
  20. //
  21. #include "IASStringEditorPage.h"
  22. //
  23. // where we can find declarations needed in this file:
  24. //
  25. #include "iashelper.h"
  26. //
  27. // END INCLUDES
  28. //////////////////////////////////////////////////////////////////////////////
  29. #include "dlgcshlp.h"
  30. IMPLEMENT_DYNCREATE(CIASPgSingleAttr, CHelpDialog)
  31. BEGIN_MESSAGE_MAP(CIASPgSingleAttr, CHelpDialog)
  32. //{{AFX_MSG_MAP(CIASPgSingleAttr)
  33. // ON_WM_CONTEXTMENU()
  34. // ON_WM_HELPINFO()
  35. ON_BN_CLICKED(IDC_RADIO_STRING, OnRadioString)
  36. ON_BN_CLICKED(IDC_RADIO_HEX, OnRadioHex)
  37. //}}AFX_MSG_MAP
  38. END_MESSAGE_MAP()
  39. //////////////////////////////////////////////////////////////////////////////
  40. /*++
  41. CIASPgSingleAttr::CIASPgSingleAttr
  42. Constructor
  43. --*/
  44. //////////////////////////////////////////////////////////////////////////////
  45. CIASPgSingleAttr::CIASPgSingleAttr() : CHelpDialog(CIASPgSingleAttr::IDD)
  46. {
  47. TRACE(_T("CIASPgSingleAttr::CIASPgSingleAttr\n"));
  48. //{{AFX_DATA_INIT(CIASPgSingleAttr)
  49. m_strAttrValue = _T("");
  50. m_strAttrFormat = _T("");
  51. m_strAttrName = _T("");
  52. m_strAttrType = _T("");
  53. m_nOctetFormatChoice = -1;
  54. //}}AFX_DATA_INIT
  55. m_OctetStringType = STRING_TYPE_NULL;
  56. m_nLengthLimit = LENGTH_LIMIT_OTHERS;
  57. //
  58. // set the initializing flag -- we shouldn't call custom data verification
  59. // routine when initializing, because otherwise we will report an error
  60. // for an attribute whose value has never been initialized
  61. //
  62. m_fInitializing = TRUE;
  63. }
  64. void CIASPgSingleAttr::OnRadioHex()
  65. {
  66. USES_CONVERSION;
  67. // convert HEX String to Unicode string, assume HEX is UTF8
  68. if(m_nOctetFormatChoice == 1) // no change
  69. return;
  70. m_nOctetFormatChoice = 1;
  71. // Take value from text field
  72. CWnd* pEdit = GetDlgItem(IDC_IAS_EDIT_ATTRVALUE);
  73. // limit the control max-chars automatically
  74. ::SendMessage(pEdit->GetSafeHwnd(), EM_LIMITTEXT, m_nLengthLimit * 2, 0);
  75. ::CString str;
  76. ASSERT(pEdit);
  77. #ifdef __WE_WANT_TO_USE_UTF8_FOR_NORMAL_STRING_AS_WELL_
  78. pEdit->GetWindowText(str);
  79. // change it to Multibyte
  80. int nLen = WideCharToMultiByte(CP_UTF8, 0, T2W((LPTSTR)(LPCTSTR)str), -1, NULL, 0, NULL, NULL);
  81. char* pData = NULL;
  82. WCHAR* pWStr = NULL;
  83. int nWStr = 0;
  84. if(nLen != 0) // when == 0 , need not to do anything
  85. {
  86. try{
  87. pData = new char[nLen];
  88. nLen = WideCharToMultiByte(CP_UTF8, 0, T2W((LPTSTR)(LPCTSTR)str), -1, pData, nLen, NULL, NULL);
  89. nWStr = BinaryToHexString(pData, nLen, NULL, 0);
  90. pWStr = new WCHAR[nWStr];
  91. // the get the HexString out
  92. BinaryToHexString(pData, nLen, pWStr, nWStr);
  93. }
  94. catch(...)
  95. {
  96. ;
  97. }
  98. }
  99. str = pWStr;
  100. delete[] pWStr;
  101. delete[] pData;
  102. #endif // __WE_WANT_TO_USE_UTF8_FOR_NORMAL_STRING_AS_WELL_
  103. // assign it to text field
  104. pEdit->SetWindowText(str);
  105. return;
  106. }
  107. void CIASPgSingleAttr::OnRadioString()
  108. {
  109. if(m_nOctetFormatChoice == 0) //no change
  110. return;
  111. m_nOctetFormatChoice = 0;
  112. // convert Unicde string to UTFs and display as hex
  113. // Take value from text field
  114. CWnd* pEdit = GetDlgItem(IDC_IAS_EDIT_ATTRVALUE);
  115. // limit the control max-chars automatically
  116. ::SendMessage(pEdit->GetSafeHwnd(), EM_LIMITTEXT, m_nLengthLimit, 0);
  117. ::CString str;
  118. ASSERT(pEdit);
  119. #ifdef __WE_WANT_TO_USE_UTF8_FOR_NORMAL_STRING_AS_WELL_
  120. pEdit->GetWindowText(str);
  121. // change it to Multibyte
  122. // need to convert UTF8
  123. int nLen = 0;
  124. char* pData = NULL;
  125. WCHAR* pWStr = NULL;
  126. int nWStr= 0;
  127. nLen = HexStringToBinary((LPTSTR)(LPCTSTR)str, NULL, 0); // find out the size of the buffer
  128. // get the binary
  129. if(nLen != 0)
  130. {
  131. try
  132. {
  133. pData = new char[nLen];
  134. ASSERT(pData);
  135. HexStringToBinary((LPTSTR)(LPCTSTR)str, pData, nLen);
  136. // UTF8 requires the flag to be 0
  137. nWStr = MultiByteToWideChar(CP_UTF8, 0, pData, nLen, NULL, 0);
  138. if(nWStr != 0) // succ
  139. {
  140. pWStr = new WCHAR[nWStr+1]; // + 1 for the addtional 0
  141. int i = 0;
  142. pWStr[nWStr] = 0;
  143. nWStr == MultiByteToWideChar(CP_UTF8, 0, pData, nLen, pWStr, nWStr);
  144. // if every char is printable
  145. for(i = 0; i < nWStr -1; i++)
  146. {
  147. if(iswprint(pWStr[i]) == 0)
  148. break;
  149. }
  150. if(0 == nWStr || i != nWStr - 1)
  151. {
  152. delete[] pWStr;
  153. pWStr = NULL;
  154. }
  155. }
  156. }
  157. catch(...)
  158. {
  159. ;
  160. }
  161. }
  162. str = pWStr;
  163. delete[] pWStr;
  164. delete[] pData;
  165. #endif
  166. // assign it to text field
  167. pEdit->SetWindowText(str);
  168. return;
  169. }
  170. //////////////////////////////////////////////////////////////////////////////
  171. /*++
  172. CIASPgSingleAttr::~CIASPgSingleAttr
  173. --*/
  174. //////////////////////////////////////////////////////////////////////////////
  175. CIASPgSingleAttr::~CIASPgSingleAttr()
  176. {
  177. TRACE(_T("CIASPgSingleAttr::~CIASPgSingleAttr\n"));
  178. }
  179. BOOL CIASPgSingleAttr::OnInitDialog()
  180. {
  181. // determine what's the length limit of the field
  182. if(m_nAttrId == RADIUS_ATTRIBUTE_FILTER_ID)
  183. {
  184. m_nLengthLimit = LENGTH_LIMIT_RADIUS_ATTRIBUTE_FILTER_ID;
  185. }
  186. else if (m_nAttrId == RADIUS_ATTRIBUTE_REPLY_MESSAGE)
  187. {
  188. m_nLengthLimit = LENGTH_LIMIT_RADIUS_ATTRIBUTE_REPLY_MESSAGE;
  189. }
  190. else
  191. {
  192. m_nLengthLimit = LENGTH_LIMIT_OTHERS;
  193. }
  194. if (m_AttrSyntax == IAS_SYNTAX_OCTETSTRING)
  195. {
  196. // turn off the text string "Attribute value"
  197. GetDlgItem(IDC_TXT_ATTRIBUTEVALUE)->ShowWindow(SW_HIDE);
  198. GetDlgItem(IDC_TXT_CHOOSEFORMAT)->ShowWindow(SW_SHOW);
  199. GetDlgItem(IDC_RADIO_STRING)->ShowWindow(SW_SHOW);
  200. GetDlgItem(IDC_RADIO_HEX)->ShowWindow(SW_SHOW);
  201. // turn on the text string to allow user choose input type
  202. if(m_OctetStringType == STRING_TYPE_HEX_FROM_BINARY)
  203. m_nOctetFormatChoice = 1; // hex string
  204. else
  205. {
  206. int n = m_strAttrValue.GetLength();
  207. // remove quotes
  208. if(n > 0 && m_strAttrValue[0] == _T('"') && m_strAttrValue[n - 1] == _T('"'))
  209. {
  210. m_strAttrValue = m_strAttrValue.Mid(1, n - 2);
  211. }
  212. m_nOctetFormatChoice = 0; // default to string
  213. }
  214. }
  215. else
  216. {
  217. GetDlgItem(IDC_TXT_ATTRIBUTEVALUE)->ShowWindow(SW_SHOW);
  218. GetDlgItem(IDC_TXT_CHOOSEFORMAT)->ShowWindow(SW_HIDE);
  219. GetDlgItem(IDC_RADIO_STRING)->ShowWindow(SW_HIDE);
  220. GetDlgItem(IDC_RADIO_HEX)->ShowWindow(SW_HIDE);
  221. }
  222. CHelpDialog::OnInitDialog();
  223. return TRUE;
  224. }
  225. //////////////////////////////////////////////////////////////////////////////
  226. /*++
  227. CIASPgSingleAttr::DoDataExchange
  228. --*/
  229. //////////////////////////////////////////////////////////////////////////////
  230. void CIASPgSingleAttr::DoDataExchange(CDataExchange* pDX)
  231. {
  232. TRACE(_T("CIASPgSingleAttr::DoDataExchange\n"));
  233. CHelpDialog::DoDataExchange(pDX);
  234. //{{AFX_DATA_MAP(CIASPgSingleAttr)
  235. DDX_Text(pDX, IDC_IAS_STATIC_ATTRFORMAT, m_strAttrFormat);
  236. DDX_Text(pDX, IDC_IAS_STATIC_ATTRNAME, m_strAttrName);
  237. DDX_Text(pDX, IDC_IAS_STATIC_ATTRTYPE, m_strAttrType);
  238. DDX_Radio(pDX, IDC_RADIO_STRING, m_nOctetFormatChoice);
  239. DDX_Text(pDX, IDC_IAS_EDIT_ATTRVALUE, m_strAttrValue);
  240. // if user input hex, then we should double the limit
  241. if(IAS_SYNTAX_OCTETSTRING == m_AttrSyntax && m_nOctetFormatChoice == 1)
  242. DDV_MaxChars(pDX, m_strAttrValue, m_nLengthLimit * 2);
  243. else
  244. DDV_MaxChars(pDX, m_strAttrValue, m_nLengthLimit);
  245. //}}AFX_DATA_MAP
  246. if ( m_fInitializing )
  247. {
  248. //
  249. // set the initializing flag -- we shouldn't call custom data verification
  250. // routine when initializing, because otherwise we will report an error
  251. // for an attribute whose value has never been initialized
  252. //
  253. m_fInitializing = FALSE;
  254. }
  255. else
  256. {
  257. switch ( m_AttrSyntax )
  258. {
  259. case IAS_SYNTAX_BOOLEAN : DDV_BoolStr(pDX, m_strAttrValue); break;
  260. case IAS_SYNTAX_INTEGER : DDV_IntegerStr(pDX, m_strAttrValue); break;
  261. case IAS_SYNTAX_UNSIGNEDINTEGER : DDV_Unsigned_IntegerStr(pDX, m_strAttrValue); break;
  262. case IAS_SYNTAX_ENUMERATOR :
  263. case IAS_SYNTAX_INETADDR :
  264. case IAS_SYNTAX_STRING :
  265. break;
  266. case IAS_SYNTAX_OCTETSTRING :
  267. // do processing based on
  268. if(!m_strAttrValue.IsEmpty() && m_nOctetFormatChoice == 1) DDV_VSA_HexString(pDX, m_strAttrValue);
  269. break;
  270. case IAS_SYNTAX_UTCTIME :
  271. case IAS_SYNTAX_PROVIDERSPECIFIC :
  272. default:
  273. // do nothing -- just normal string
  274. break;
  275. }
  276. }
  277. // calculate string value based on display string typed in by user
  278. if(pDX->m_bSaveAndValidate && m_AttrSyntax == IAS_SYNTAX_OCTETSTRING)
  279. {
  280. switch(m_nOctetFormatChoice)
  281. {
  282. case 0: // Unicode string , need to convert to UTF-8
  283. m_OctetStringType = STRING_TYPE_UNICODE;
  284. break;
  285. case 1: // HEX, need to covert to binary
  286. m_OctetStringType = STRING_TYPE_HEX_FROM_BINARY;
  287. break;
  288. default:
  289. ASSERT(0); // this should not happen
  290. break;
  291. }
  292. }
  293. }
  294. /////////////////////////////////////////////////////////////////////////////
  295. // CIASPgSingleAttr message handlers