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.

1310 lines
32 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
  4. /**********************************************************************/
  5. /*
  6. rasdial.cpp
  7. Definition of CRASProfile class and CRASUser class
  8. FILE HISTORY:
  9. */
  10. //////////////////////////////////////////////////////////////////////
  11. #include "stdafx.h"
  12. #include <sspi.h>
  13. #include <secext.h>
  14. #include <dsgetdc.h>
  15. #include "resource.h"
  16. #include "helper.h"
  17. #include "rasdial.h"
  18. #include "rasprof.h"
  19. #include "sharesdo.h"
  20. #define _WEI_DEBUG
  21. #ifdef _DEBUG
  22. #undef THIS_FILE
  23. static char THIS_FILE[]=__FILE__;
  24. #define new DEBUG_NEW
  25. #endif
  26. #define ERRORCODE_NOTFOUND ERROR_FILE_NOT_FOUND // win32 error
  27. CRASUserMerge::CRASUserMerge(RasEnvType type, LPCWSTR location, LPCWSTR userPath)
  28. {
  29. // environment info
  30. m_type = type;
  31. m_strMachine = location;
  32. m_strUserPath = userPath;
  33. // Ip Addresses
  34. m_dwFramedIPAddress = 0;
  35. m_dwDefinedAttribMask = 0;
  36. };
  37. HRESULT CRASUserMerge::HrGetDCName(CString& DcName)
  38. {
  39. HRESULT hr = S_OK;
  40. VARIANT v;
  41. VariantInit(&v);
  42. CComPtr<IADs> spIADs;
  43. CComPtr<IADsObjectOptions> spOps;
  44. USES_CONVERSION;
  45. CHECK_HR( hr = ADsGetObject(T2W((LPTSTR)(LPCTSTR)m_strUserPath), IID_IADs, (void**)&spIADs));
  46. ASSERT(spIADs.p);
  47. CHECK_HR(hr = spIADs->QueryInterface(IID_IADsObjectOptions,(void**)&spOps));
  48. CHECK_HR(hr = spOps->GetOption(ADS_OPTION_SERVERNAME,&v));
  49. ASSERT(V_VT(&v) == VT_BSTR);
  50. DcName = V_BSTR(&v);
  51. VariantClear(&v);
  52. L_ERR:
  53. VariantClear(&v);
  54. return hr;
  55. };
  56. HRESULT CRASUserMerge::HrIsInMixedDomain()
  57. {
  58. HRESULT hr = S_OK;
  59. VARIANT v;
  60. VariantInit(&v);
  61. if(!m_strMachine.IsEmpty()) // local user, so not
  62. return S_FALSE;
  63. else
  64. {
  65. // try to use SDO
  66. IASDOMAINTYPE domainType;
  67. if((ISdoMachine*)m_spISdoServer != NULL) // already created
  68. {
  69. if(m_spISdoServer->GetDomainType(&domainType) == S_OK)
  70. {
  71. if (domainType == DOMAIN_TYPE_MIXED)
  72. return S_OK;
  73. else
  74. return S_FALSE;
  75. }
  76. }
  77. // if for any reason, SDO doesn't provide the information, do it myself
  78. // Canonical Name Format
  79. TCHAR szName[MAX_PATH * 2];
  80. ULONG size = MAX_PATH * 2;
  81. CString DomainPath;
  82. CString strTemp;
  83. CComPtr<IADs> spIADs;
  84. int i;
  85. USES_CONVERSION;
  86. CHECK_HR( hr = ADsGetObject(T2W((LPTSTR)(LPCTSTR)m_strUserPath), IID_IADs, (void**)&spIADs));
  87. ASSERT(spIADs.p);
  88. CHECK_HR( hr = spIADs->Get(L"distinguishedName", &v));
  89. ASSERT(V_VT(&v) == VT_BSTR);
  90. CHECK_HR(hr = ::TranslateName(V_BSTR(&v), NameFullyQualifiedDN, NameCanonical, szName, &size));
  91. VariantClear(&v);
  92. strTemp = szName;
  93. i = strTemp.Find(_T('/'));
  94. if(i != -1)
  95. strTemp = strTemp.Left(i);
  96. // DN of the domain
  97. DomainPath = _T("LDAP://");
  98. DomainPath += strTemp;
  99. spIADs.Release();
  100. CHECK_HR(hr = ADsGetObject(T2W((LPTSTR)(LPCTSTR)DomainPath), IID_IADs, (void**)&spIADs));
  101. ASSERT(spIADs.p);
  102. CHECK_HR(hr = spIADs->Get(L"nTMixedDomain", &v));
  103. ASSERT(V_VT(&v) == VT_BOOL || V_VT(&v) == VT_I4);
  104. if(V_BOOL(&v)) hr = S_OK;
  105. else hr = S_FALSE;
  106. }
  107. L_ERR:
  108. VariantClear(&v);
  109. return hr;
  110. }
  111. BOOL CRASUserMerge::IfAccessAttribute(ULONG id)
  112. {
  113. if(S_OK == HrIsInMixedDomain()) // only allow dialin bit and callback policy
  114. {
  115. switch(id)
  116. {
  117. case PROPERTY_USER_IAS_ATTRIBUTE_ALLOW_DIALIN: // allow dialin or not
  118. case PROPERTY_USER_msRADIUSCallbackNumber: // call back number
  119. case PROPERTY_USER_RADIUS_ATTRIBUTE_SERVICE_TYPE: // call back policy
  120. return TRUE;
  121. default:
  122. return FALSE;
  123. }
  124. }
  125. else // no restriction otherwise
  126. return TRUE;
  127. }
  128. HRESULT CRASUserMerge::SetRegistryFootPrint()
  129. {
  130. if(IsFocusOnLocalUser())
  131. {
  132. RegKey RemoteAccessParames;
  133. LONG lRes = RemoteAccessParames.Create(RAS_REG_ROOT, REGKEY_REMOTEACCESS_PARAMS,
  134. REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, (LPCTSTR)m_strMachine);
  135. if (lRes != ERROR_SUCCESS)
  136. return HRESULT_FROM_WIN32(lRes);
  137. //================================================
  138. // save the values to the key
  139. DWORD regValue = REGVAL_VAL_USERSCONFIGUREDWITHMMC;
  140. lRes = RemoteAccessParames.SetValue(REGVAL_NAME_USERSCONFIGUREDWITHMMC, regValue);
  141. }
  142. return S_OK;
  143. }
  144. //====================================================
  145. //
  146. // CRASUserMerge::Load
  147. //
  148. // load RASUser object from DS
  149. // pcwszUserPath: is the ADsPath of the DSuser object, the RASUser object is
  150. // object contained in DSUser object
  151. // when, the RASUser object doesn't exist, load will call
  152. // CreateDefault to create one object for this DSUser
  153. HRESULT CRASUserMerge::Load()
  154. {
  155. // new function added for no DS machine : weijiang 12/17/97
  156. USES_CONVERSION;
  157. TRACE(_T("Enter CRASUserMerge::Load()\r\n"));
  158. // Load is not expected to be called more than once
  159. ASSERT(!m_spISdoServer.p);
  160. VARIANT var;
  161. HRESULT hr = S_OK;
  162. CComPtr<ISdo> spSdo;
  163. CComPtr<IUnknown> spUnk;
  164. BSTR bstrMachineName = NULL;
  165. BSTR bstrUserPath = NULL;
  166. UINT nServiceType = 0;
  167. IASDATASTORE storeFlags;
  168. CComPtr<ISdo> spIRasUser;
  169. VariantInit(&var);
  170. // one more function call to SDOSERver to set machine information
  171. // Get the user SDO
  172. if(m_strMachine.IsEmpty()) // focused on DS
  173. {
  174. storeFlags = DATA_STORE_DIRECTORY;
  175. CString sDCName;
  176. CHECK_HR(hr = HrGetDCName(sDCName));
  177. CBSTR bstrDomainController(sDCName);
  178. bstrMachineName = T2BSTR((LPTSTR)(LPCTSTR)sDCName);
  179. }
  180. else // local machine
  181. {
  182. storeFlags = DATA_STORE_LOCAL;
  183. bstrMachineName = T2BSTR((LPTSTR)(LPCTSTR)m_strMachine);
  184. }
  185. // connect to server
  186. #ifdef SINGLE_SDO_CONNECTION // for share the same sdo connection for multiple users
  187. // connection will NOT be necessary after SDO changes to RTM version.
  188. // connect once for each process
  189. CHECK_HR(hr = m_MarshalSdoServer.GetServer(&m_spISdoServer));
  190. {
  191. CWaitCursor wc;
  192. // if we get the server back from the shareSDO object, we use it to connect
  193. if ((ISdoMachine*)m_spISdoServer)
  194. {
  195. CHECK_HR(hr = m_MarshalSdoServer.Connect());
  196. }
  197. // otherwise, we make a new connection
  198. else
  199. {
  200. // try to Connect the old way
  201. // connect everytime a user page is requested
  202. CHECK_HR(hr = ConnectToSdoServer(bstrMachineName, NULL, NULL, &m_spISdoServer));
  203. }
  204. }
  205. #else
  206. // connect everytime a user page is requested
  207. CHECK_HR(hr = ConnectToSdoServer(bstrMachineName, NULL, NULL, &m_spISdoServer));
  208. #endif
  209. // If for local users, only NT5 servers are allowed to configure using this apge
  210. if(!m_strMachine.IsEmpty()) // not focused on DS
  211. {
  212. IASOSTYPE OSType;
  213. CHECK_HR(hr = m_spISdoServer->GetOSType(&OSType));
  214. if(OSType != SYSTEM_TYPE_NT5_SERVER)
  215. {
  216. hr = S_FALSE;
  217. goto L_ERR;
  218. }
  219. }
  220. // find the user object
  221. bstrUserPath = T2BSTR((LPTSTR)(LPCTSTR)m_strUserPath);
  222. TracePrintf(g_dwTraceHandle,_T("SdoServer::GetUserSDO(%x, %s, %x"), storeFlags, bstrUserPath, &spUnk);
  223. CHECK_HR(hr = m_spISdoServer->GetUserSDO( storeFlags, bstrUserPath, &spUnk));
  224. TracePrintf(g_dwTraceHandle,_T(" hr = %8x\r\n"), hr);
  225. ASSERT(spUnk.p);
  226. CHECK_HR(hr = spUnk->QueryInterface(IID_ISdo, (void**)&spIRasUser));
  227. ASSERT(spIRasUser.p);
  228. // initialize the wrapper class
  229. CHECK_HR(hr = m_SdoWrapper.Init((ISdo*)spIRasUser));
  230. // Get All the properties
  231. // need to handle the case when the values don't exist
  232. TRACE(_T("Getting Properties\r\n"));
  233. m_dwDefinedAttribMask = 0;
  234. // m_dwDialinPermit
  235. VariantClear(&var);
  236. CHECK_HR(hr = m_SdoWrapper.GetProperty(PROPERTY_USER_IAS_ATTRIBUTE_ALLOW_DIALIN, &var));
  237. if(V_VT(&var) == VT_I4 || V_VT(&var) == VT_BOOL)
  238. {
  239. if(V_BOOL(&var) != 0)
  240. m_dwDialinPermit = 1;
  241. else
  242. m_dwDialinPermit = 0;
  243. }
  244. else
  245. m_dwDialinPermit = -1; // the value is not defined in the user data, using policy to decide
  246. // FramedIPAddress
  247. VariantClear(&var);
  248. CHECK_HR(hr = m_SdoWrapper.GetProperty(PROPERTY_USER_msRADIUSFramedIPAddress, &var));
  249. if(V_VT(&var) == VT_I4)
  250. {
  251. m_dwDefinedAttribMask |= RAS_USE_STATICIP;
  252. m_dwFramedIPAddress = V_I4(&var);
  253. }
  254. else
  255. {
  256. VariantClear(&var);
  257. CHECK_HR(hr = m_SdoWrapper.GetProperty(PROPERTY_USER_msSavedRADIUSFramedIPAddress, &var));
  258. if(V_VT(&var) == VT_I4)
  259. m_dwFramedIPAddress = V_I4(&var);
  260. else
  261. m_dwFramedIPAddress = 0;
  262. }
  263. // Service Type -- to hold if this user has callback, if this user allowed to dialin
  264. VariantClear(&var);
  265. CHECK_HR(hr = m_SdoWrapper.GetProperty(PROPERTY_USER_RADIUS_ATTRIBUTE_SERVICE_TYPE, &var));
  266. if(V_VT(&var) == VT_I4)
  267. {
  268. nServiceType = V_I4(&var);
  269. }
  270. // call back number
  271. VariantClear(&var);
  272. CHECK_HR(hr = m_SdoWrapper.GetProperty(PROPERTY_USER_msRADIUSCallbackNumber, &var));
  273. if(V_VT(&var) == VT_BSTR)
  274. {
  275. m_strCallbackNumber = V_BSTR(&var);
  276. if(nServiceType == RADUIS_SERVICETYPE_CALLBACK_FRAME && m_strCallbackNumber.IsEmpty())
  277. m_dwDefinedAttribMask |= RAS_CALLBACK_CALLERSET;
  278. else if (nServiceType == RADUIS_SERVICETYPE_CALLBACK_FRAME)
  279. m_dwDefinedAttribMask |= RAS_CALLBACK_SECURE;
  280. }
  281. else
  282. {
  283. if(nServiceType == RADUIS_SERVICETYPE_CALLBACK_FRAME)
  284. m_dwDefinedAttribMask |= RAS_CALLBACK_CALLERSET;
  285. else
  286. m_dwDefinedAttribMask |= RAS_CALLBACK_NOCALLBACK;
  287. VariantClear(&var);
  288. CHECK_HR(hr = m_SdoWrapper.GetProperty(PROPERTY_USER_msSavedRADIUSCallbackNumber, &var));
  289. if(V_VT(&var) == VT_BSTR)
  290. m_strCallbackNumber = V_BSTR(&var);
  291. }
  292. // calling station id
  293. VariantClear(&var);
  294. CHECK_HR(hr = m_SdoWrapper.GetProperty(PROPERTY_USER_msNPCallingStationID, &var));
  295. if(V_VT(&var) & VT_ARRAY)
  296. {
  297. m_strArrayCallingStationId = V_ARRAY(&var);
  298. m_dwDefinedAttribMask |= RAS_USE_CALLERID;
  299. }
  300. else
  301. {
  302. VariantClear(&var);
  303. CHECK_HR(hr = m_SdoWrapper.GetProperty(PROPERTY_USER_msSavedNPCallingStationID, &var));
  304. if(V_VT(&var) & VT_ARRAY)
  305. m_strArrayCallingStationId = V_ARRAY(&var);
  306. }
  307. // framed routes
  308. VariantClear(&var);
  309. CHECK_HR(hr = m_SdoWrapper.GetProperty(PROPERTY_USER_msRADIUSFramedRoute, &var));
  310. if(V_VT(&var) & VT_ARRAY)
  311. {
  312. m_strArrayFramedRoute = V_ARRAY(&var);
  313. m_dwDefinedAttribMask |= RAS_USE_STATICROUTES;
  314. }
  315. else
  316. {
  317. VariantClear(&var);
  318. CHECK_HR(hr = m_SdoWrapper.GetProperty(PROPERTY_USER_msSavedRADIUSFramedRoute, &var));
  319. if(V_VT(&var) & VT_ARRAY)
  320. m_strArrayFramedRoute = V_ARRAY(&var);
  321. }
  322. L_ERR:
  323. TracePrintf(g_dwTraceHandle, _T("hr = %8x\r\n"), hr);
  324. VariantClear(&var);
  325. SysFreeString(bstrMachineName);
  326. SysFreeString(bstrUserPath);
  327. TracePrintf(g_dwTraceHandle, _T("Leave CRASUserMerge::Load(), hr = %8x\r\n"), hr);
  328. return hr;
  329. }
  330. //====================================================
  331. // CRASUserMerge::Save
  332. //
  333. // save ths RASUser object
  334. HRESULT CRASUserMerge::Save()
  335. {
  336. TRACE(_T("Enter CRASUserMerge::Save()\r\n"));
  337. HRESULT hr = S_OK;
  338. VARIANT var;
  339. USES_CONVERSION;
  340. // restore SDO user from
  341. // otherwise, we could overwrite the other properties in usrparams field
  342. // fix bug: 86968
  343. m_SdoWrapper.Commit(FALSE);
  344. VariantInit(&var);
  345. //==========================
  346. // Dialin bit
  347. VariantClear(&var);
  348. V_VT(&var) = VT_BOOL;
  349. switch(m_dwDialinPermit)
  350. {
  351. case 1: // allow
  352. case 0: // deny
  353. if(m_dwDialinPermit == 1)
  354. V_I4(&var) = VARIANT_TRUE; // Variant TRUE
  355. else
  356. V_I4(&var) = VARIANT_FALSE;
  357. CHECK_HR(hr = m_SdoWrapper.PutProperty(PROPERTY_USER_IAS_ATTRIBUTE_ALLOW_DIALIN, &var));
  358. break;
  359. case -1: // decide by policy -- remove attribute
  360. CHECK_HR(hr = m_SdoWrapper.RemoveProperty(PROPERTY_USER_IAS_ATTRIBUTE_ALLOW_DIALIN));
  361. break;
  362. default:
  363. ASSERT(0); // if need to provide new code
  364. }
  365. //==========================
  366. // Service Type -- callback policy
  367. if(m_dwDefinedAttribMask & (RAS_CALLBACK_SECURE | RAS_CALLBACK_CALLERSET))
  368. {
  369. VariantClear(&var);
  370. V_VT(&var) = VT_I4;
  371. V_I4(&var) = RADUIS_SERVICETYPE_CALLBACK_FRAME;
  372. CHECK_HR(hr = m_SdoWrapper.PutProperty(PROPERTY_USER_RADIUS_ATTRIBUTE_SERVICE_TYPE, &var));
  373. }
  374. else
  375. CHECK_HR(hr = m_SdoWrapper.RemoveProperty(PROPERTY_USER_RADIUS_ATTRIBUTE_SERVICE_TYPE));
  376. //==========================
  377. // call back number
  378. if (!m_strCallbackNumber.IsEmpty() && (m_dwDefinedAttribMask & RAS_CALLBACK_SECURE))
  379. {
  380. VariantClear(&var);
  381. V_VT(&var) = VT_BSTR;
  382. V_BSTR(&var) = T2BSTR((LPTSTR)(LPCTSTR)m_strCallbackNumber);
  383. CHECK_HR(hr = m_SdoWrapper.PutProperty(PROPERTY_USER_msRADIUSCallbackNumber, &var));
  384. }
  385. else
  386. CHECK_HR(hr = m_SdoWrapper.RemoveProperty(PROPERTY_USER_msRADIUSCallbackNumber));
  387. if(S_OK != HrIsInMixedDomain())
  388. {
  389. //==========================
  390. // call back number
  391. if(!m_strCallbackNumber.IsEmpty())
  392. {
  393. VariantClear(&var);
  394. V_VT(&var) = VT_BSTR;
  395. V_BSTR(&var) = T2BSTR((LPTSTR)(LPCTSTR)m_strCallbackNumber);
  396. CHECK_HR(hr = m_SdoWrapper.PutProperty(PROPERTY_USER_msSavedRADIUSCallbackNumber, &var));
  397. }
  398. else
  399. CHECK_HR(hr = m_SdoWrapper.RemoveProperty(PROPERTY_USER_msSavedRADIUSCallbackNumber));
  400. //==========================
  401. // FramedIPAddress
  402. if(m_dwFramedIPAddress) // need to back up the data, no matter if it's used
  403. {
  404. VariantClear(&var);
  405. V_VT(&var) = VT_I4;
  406. V_I4(&var) = m_dwFramedIPAddress;
  407. CHECK_HR(hr = m_SdoWrapper.PutProperty(PROPERTY_USER_msSavedRADIUSFramedIPAddress, &var));
  408. }
  409. else // remove it
  410. CHECK_HR(hr = m_SdoWrapper.RemoveProperty(PROPERTY_USER_msSavedRADIUSFramedIPAddress));
  411. if(m_dwFramedIPAddress && (m_dwDefinedAttribMask & RAS_USE_STATICIP))
  412. {
  413. CHECK_HR(hr = m_SdoWrapper.PutProperty(PROPERTY_USER_msRADIUSFramedIPAddress, &var));
  414. }
  415. else
  416. CHECK_HR(hr = m_SdoWrapper.RemoveProperty(PROPERTY_USER_msRADIUSFramedIPAddress));
  417. }
  418. //==========================
  419. // calling station id
  420. if(S_OK != HrIsInMixedDomain())
  421. {
  422. if(m_strArrayCallingStationId.GetSize())
  423. {
  424. VariantClear(&var);
  425. V_VT(&var) = VT_VARIANT | VT_ARRAY;
  426. V_ARRAY(&var) = (SAFEARRAY*)m_strArrayCallingStationId;
  427. CHECK_HR(hr = m_SdoWrapper.PutProperty(PROPERTY_USER_msSavedNPCallingStationID, &var));
  428. }
  429. else
  430. CHECK_HR(hr = m_SdoWrapper.RemoveProperty(PROPERTY_USER_msSavedNPCallingStationID));
  431. if(m_strArrayCallingStationId.GetSize() && (m_dwDefinedAttribMask & RAS_USE_CALLERID))
  432. {
  433. CHECK_HR(hr = m_SdoWrapper.PutProperty(PROPERTY_USER_msNPCallingStationID, &var));
  434. }
  435. else
  436. CHECK_HR(hr = m_SdoWrapper.RemoveProperty(PROPERTY_USER_msNPCallingStationID));
  437. //==========================
  438. // framed routes
  439. if(m_strArrayFramedRoute.GetSize())
  440. {
  441. VariantClear(&var);
  442. V_VT(&var) = VT_VARIANT | VT_ARRAY;
  443. V_ARRAY(&var) = (SAFEARRAY*)m_strArrayFramedRoute;
  444. CHECK_HR(hr = m_SdoWrapper.PutProperty(PROPERTY_USER_msSavedRADIUSFramedRoute, &var));
  445. }
  446. else
  447. CHECK_HR(hr = m_SdoWrapper.RemoveProperty(PROPERTY_USER_msSavedRADIUSFramedRoute));
  448. if(m_strArrayFramedRoute.GetSize() && (m_dwDefinedAttribMask & RAS_USE_STATICROUTES))
  449. {
  450. CHECK_HR(hr = m_SdoWrapper.PutProperty(PROPERTY_USER_msRADIUSFramedRoute, &var));
  451. }
  452. else
  453. CHECK_HR(hr = m_SdoWrapper.RemoveProperty(PROPERTY_USER_msRADIUSFramedRoute));
  454. }
  455. CHECK_HR(hr = m_SdoWrapper.Commit());
  456. // touch the registry to make connection UI know.
  457. SetRegistryFootPrint();
  458. L_ERR:
  459. VariantClear(&var);
  460. TRACE(_T("Leave CRASUserMerge::Save()\r\n"));
  461. return hr;
  462. }
  463. // to detect if driver level support 128 bit encryption,
  464. HRESULT CRASProfileMerge::GetRasNdiswanDriverCaps(RAS_NDISWAN_DRIVER_INFO *pInfo)
  465. {
  466. HANDLE hConn;
  467. RAS_NDISWAN_DRIVER_INFO pDriverInfo;
  468. DWORD dwErr = RasRpcConnectServer((LPTSTR)(LPCTSTR)m_strMachineName, &hConn);
  469. if (dwErr != NOERROR)
  470. return HRESULT_FROM_WIN32(dwErr);
  471. dwErr = RasGetNdiswanDriverCaps(hConn, pInfo);
  472. RasRpcDisconnectServer(hConn);
  473. return HRESULT_FROM_WIN32(dwErr);
  474. }
  475. #define EAP_TLS_ID 13
  476. // EAP type list -- !!! Need to implement
  477. HRESULT CRASProfileMerge::GetEapTypeList(
  478. CStrArray& EapTypes,
  479. CDWArray& EapIds,
  480. CDWArray& EAPTypeKeys,
  481. AuthProviderArray* pProvList)
  482. {
  483. HRESULT hr = S_OK;
  484. #ifndef __EAPLIST_USES_SDO__
  485. AuthProviderArray __tmpArray;
  486. CString* pStr = NULL;
  487. DWORD dwID;
  488. DWORD dwKey;
  489. int i;
  490. if(!pProvList) // if not provided
  491. pProvList = &__tmpArray;
  492. CHECK_HR(hr = GetEapProviders(m_strMachineName, pProvList));
  493. // fill in the buffers for name, Id, and keys
  494. for(i = 0; i < pProvList->GetSize(); i++)
  495. {
  496. AuthProviderData* pProv = &(pProvList->ElementAt(i));
  497. try
  498. {
  499. pStr = new CString(pProv->m_stTitle);
  500. dwID = _ttol(pProv->m_stKey);
  501. dwKey = pProv->m_fSupportsEncryption;
  502. // put the above to the arrays
  503. EapIds.Add(dwID);
  504. EAPTypeKeys.Add(dwKey);
  505. EapTypes.Add(pStr);
  506. }
  507. catch(CMemoryException&)
  508. {
  509. EapIds.DeleteAll();
  510. EAPTypeKeys.DeleteAll();
  511. EapTypes.DeleteAll();
  512. CHECK_HR(hr = E_OUTOFMEMORY);
  513. }
  514. }
  515. #else
  516. ASSERT(m_spIDictionary.p);
  517. VARIANT vNames;
  518. VARIANT vIds;
  519. int j, count;
  520. VariantInit(&vNames);
  521. VariantInit(&vIds);
  522. CString* pStr = NULL;
  523. DWORD dwKey = 0;
  524. CHECK_HR(hr = m_spIDictionary->EnumAttributeValues((ATTRIBUTEID)PROPERTY_PROFILE_msNPAllowedEapType, &vIds, &vNames));
  525. ASSERT(V_VT(&vNames) & VT_ARRAY);
  526. ASSERT(V_VT(&vIds) & VT_ARRAY);
  527. EAPTypeKeys.DeleteAll();
  528. try{
  529. EapTypes = (SAFEARRAY*)V_ARRAY(&vNames);
  530. EapIds = (SAFEARRAY*)V_ARRAY(&vIds);
  531. }
  532. catch(CMemoryException&)
  533. {
  534. hr = E_OUTOFMEMORY;
  535. }
  536. ASSERT(EapIds.GetSize() == EapTypes.GetSize()); // they need to be in pairs
  537. count = EapTypes.GetSize();
  538. if(EapIds.GetSize() != count)
  539. hr = E_FAIL;
  540. // remove the leading charater for EapKey and put the key into a separate array
  541. for(j = 0; j < count; j++)
  542. {
  543. CString* pStr = EapTypes.GetAt(j);
  544. ASSERT(pStr);
  545. pStr->TrimLeft();
  546. pStr->TrimRight();
  547. dwKey = (pStr->GetAt(0) == _T('1'));
  548. int i = pStr->Find(_T(':'));
  549. if(i != -1)
  550. *pStr = pStr->Mid(i + 1);
  551. EAPTypeKeys.Add(dwKey);
  552. // append TLS string with RAS specific
  553. if(EapIds.GetAt(j) == EAP_TLS_ID)
  554. {
  555. CString str;
  556. str.LoadString(IDS_RASSPECIFIC);
  557. *pStr += str;
  558. }
  559. }
  560. #endif
  561. L_ERR:
  562. return hr;
  563. }
  564. // Medium Type list -- !! Need to implement
  565. HRESULT CRASProfileMerge::GetPortTypeList(CStrArray& Names, CDWArray& MediumIds)
  566. {
  567. TRACE(_T("Enter CRASProfileMerge::GetPortTypeList\n"));
  568. ASSERT(m_spIDictionary.p);
  569. VARIANT vNames;
  570. VARIANT vIds;
  571. VariantInit(&vNames);
  572. VariantInit(&vIds);
  573. HRESULT hr = S_OK;
  574. CHECK_HR(hr = m_spIDictionary->EnumAttributeValues((ATTRIBUTEID)PROPERTY_PROFILE_msNPAllowedPortTypes, &vIds, &vNames));
  575. ASSERT(V_VT(&vNames) & VT_ARRAY);
  576. ASSERT(V_VT(&vIds) & VT_ARRAY);
  577. try{
  578. Names = (SAFEARRAY*)V_ARRAY(&vNames);
  579. MediumIds = (SAFEARRAY*)V_ARRAY(&vIds);
  580. }
  581. catch(CMemoryException&)
  582. {
  583. hr = E_OUTOFMEMORY;
  584. }
  585. ASSERT(MediumIds.GetSize() == Names.GetSize()); // they need to be in pairs
  586. if(MediumIds.GetSize() != Names.GetSize())
  587. hr = E_FAIL;
  588. L_ERR:
  589. TRACE(_T("Leave CRASProfileMerge::GetPortTypeList\n"));
  590. return hr;
  591. }
  592. //====================================================
  593. //
  594. // CRASProfileMerge::Load
  595. //
  596. // pcwszRelativePath -- the relative name for the profile object
  597. //
  598. HRESULT CRASProfileMerge::Load()
  599. {
  600. TRACE(_T("Enter CRASProfileMerge::Load()\r\n"));
  601. // ==
  602. ASSERT(m_spIProfile.p);
  603. ASSERT(m_spIDictionary.p);
  604. VARIANT var;
  605. HRESULT hr = S_OK;
  606. // Init the flags to NULL, each bit of the flag is used tell if a particular
  607. // attribute is defined
  608. m_dwAttributeFlags = 0;
  609. VariantInit(&var);
  610. //==================================================
  611. // constraints dialog
  612. /*
  613. // Constraints Dialog
  614. PROPERTY_PROFILE_msNPTimeOfDay
  615. PROPERTY_PROFILE_msNPCalledStationId
  616. PROPERTY_PROFILE_msNPAllowedPortTypes
  617. PROPERTY_PROFILE_msRADIUSIdleTimeout
  618. PROPERTY_PROFILE_msRADIUSSessionTimeout
  619. */
  620. // Sessions Allowed
  621. CHECK_HR(hr = m_SdoWrapper.Init(PROPERTY_PROFILE_ATTRIBUTES_COLLECTION, m_spIProfile, m_spIDictionary));
  622. // Time Of Day
  623. VariantClear(&var);
  624. CHECK_HR(hr = m_SdoWrapper.GetProperty(PROPERTY_PROFILE_msNPTimeOfDay, &var));
  625. if(V_VT(&var) & VT_ARRAY)
  626. {
  627. m_strArrayTimeOfDay = V_ARRAY(&var);
  628. m_dwAttributeFlags |= PABF_msNPTimeOfDay;
  629. }
  630. else
  631. m_strArrayTimeOfDay.DeleteAll();
  632. // called station id
  633. VariantClear(&var);
  634. CHECK_HR(hr = m_SdoWrapper.GetProperty(PROPERTY_PROFILE_msNPCalledStationId, &var));
  635. if(V_VT(&var) & VT_ARRAY)
  636. {
  637. m_strArrayCalledStationId = V_ARRAY(&var);
  638. m_dwAttributeFlags |= PABF_msNPCalledStationId;
  639. }
  640. else
  641. m_strArrayCalledStationId.DeleteAll();
  642. // allowed port types
  643. VariantClear(&var);
  644. CHECK_HR(hr = m_SdoWrapper.GetProperty(PROPERTY_PROFILE_msNPAllowedPortTypes, &var));
  645. if(V_VT(&var) & VT_ARRAY)
  646. {
  647. m_dwArrayAllowedPortTypes = V_ARRAY(&var);
  648. m_dwAttributeFlags |= PABF_msNPAllowedPortTypes;
  649. }
  650. else
  651. m_dwArrayAllowedPortTypes.DeleteAll();
  652. // idle timeout
  653. VariantClear(&var);
  654. CHECK_HR(hr = m_SdoWrapper.GetProperty(PROPERTY_PROFILE_msRADIUSIdleTimeout, &var));
  655. if(V_VT(&var) == VT_I4)
  656. {
  657. m_dwIdleTimeout = V_I4(&var);
  658. m_dwAttributeFlags |= PABF_msRADIUSIdleTimeout;
  659. }
  660. else
  661. m_dwIdleTimeout = RAS_DEF_IDLETIMEOUT;
  662. // session time out
  663. VariantClear(&var);
  664. CHECK_HR(hr = m_SdoWrapper.GetProperty(PROPERTY_PROFILE_msRADIUSSessionTimeout, &var));
  665. if(V_VT(&var) == VT_I4)
  666. {
  667. m_dwSessionTimeout = V_I4(&var);
  668. m_dwAttributeFlags |= PABF_msRADIUSSessionTimeout;
  669. }
  670. else
  671. m_dwSessionTimeout = RAS_DEF_SESSIONTIMEOUT;
  672. //============================================
  673. // networking
  674. /*
  675. // Networking Dialog
  676. PROPERTY_PROFILE_msRADIUSFramedIPAddress
  677. */
  678. // framedIPAddress -- ip address assignment poilcy
  679. VariantClear(&var);
  680. CHECK_HR(hr = m_SdoWrapper.GetProperty(PROPERTY_PROFILE_msRADIUSFramedIPAddress, &var));
  681. if(V_VT(&var) == VT_I4)
  682. {
  683. m_dwFramedIPAddress = V_I4(&var);
  684. m_dwAttributeFlags |= PABF_msRADIUSFramedIPAddress;
  685. }
  686. else
  687. m_dwFramedIPAddress = RAS_DEF_IPADDRESSPOLICY;
  688. // filters
  689. VariantClear(&var);
  690. CHECK_HR(hr = m_SdoWrapper.GetProperty(PROPERTY_PROFILE_msRASFilter, &var));
  691. #ifdef FILTERS_AS_BSTR
  692. if(V_VT(&var) == VT_BSTR)
  693. {
  694. m_cbstrFilters.AssignBSTR(V_BSTR(&var));
  695. m_dwAttributeFlags |= PAFB_msRASFilter;
  696. }
  697. #else // SAFEARRAY of UI1
  698. if(V_VT(&var) & VT_ARRAY)
  699. {
  700. CBYTEArray ba((SAFEARRAY*)V_ARRAY(&var));
  701. DWORD i = ba.GetSize();
  702. if(i > 0)
  703. {
  704. PBYTE pByte = (PBYTE)malloc(i);
  705. if(pByte == NULL)
  706. CHECK_HR(hr = E_OUTOFMEMORY); // jmp to error handling here
  707. DWORD j = i;
  708. ba.GetBlob(pByte, &i);
  709. ASSERT( i == j);
  710. m_cbstrFilters.AssignBlob((const char *)pByte, i);
  711. free(pByte);
  712. if((BSTR)m_cbstrFilters == NULL)
  713. CHECK_HR(hr = E_OUTOFMEMORY);
  714. m_nFiltersSize = i;
  715. m_dwAttributeFlags |= PAFB_msRASFilter;
  716. }
  717. }
  718. #endif
  719. else
  720. {
  721. m_cbstrFilters.Clean();
  722. m_nFiltersSize = 0;
  723. }
  724. //==============================================
  725. // multilink
  726. /*
  727. // Multilink Dialog
  728. PROPERTY_PROFILE_msRADIUSPortLimit
  729. PROPERTY_PROFILE_msRASBapLinednLimit
  730. PROPERTY_PROFILE_msRASBapLinednTime
  731. PROPERTY_PROFILE_msRASBapRequired
  732. */
  733. // port limit
  734. VariantClear(&var);
  735. CHECK_HR(hr = m_SdoWrapper.GetProperty(PROPERTY_PROFILE_msRADIUSPortLimit, &var));
  736. if(V_VT(&var) == VT_I4)
  737. {
  738. m_dwPortLimit = V_I4(&var);
  739. m_dwAttributeFlags |= PABF_msRADIUSPortLimit;
  740. }
  741. else
  742. m_dwPortLimit = RAS_DEF_PORTLIMIT;
  743. // BAP required
  744. VariantClear(&var);
  745. CHECK_HR(hr = m_SdoWrapper.GetProperty(PROPERTY_PROFILE_msRASBapRequired, &var));
  746. if(V_VT(&var) == VT_I4)
  747. {
  748. m_dwBapRequired = V_I4(&var);
  749. m_dwAttributeFlags |= PABF_msRASBapRequired;
  750. }
  751. else
  752. m_dwBapRequired = RAS_DEF_BAPREQUIRED;
  753. // line down limit
  754. VariantClear(&var);
  755. CHECK_HR(hr = m_SdoWrapper.GetProperty(PROPERTY_PROFILE_msRASBapLinednLimit, &var));
  756. if(V_VT(&var) == VT_I4)
  757. {
  758. m_dwBapLineDnLimit = V_I4(&var);
  759. m_dwAttributeFlags |= PABF_msRASBapLinednLimit;
  760. }
  761. else
  762. m_dwBapLineDnLimit = RAS_DEF_BAPLINEDNLIMIT;
  763. // line down time
  764. VariantClear(&var);
  765. CHECK_HR(hr = m_SdoWrapper.GetProperty(PROPERTY_PROFILE_msRASBapLinednTime, &var));
  766. if(V_VT(&var) == VT_I4)
  767. {
  768. m_dwBapLineDnTime = V_I4(&var);
  769. m_dwAttributeFlags |= PABF_msRASBapLinednTime;
  770. }
  771. else
  772. m_dwBapLineDnTime = RAS_DEF_BAPLINEDNTIME;
  773. //==================================
  774. // authentication
  775. /*
  776. // Authentication Dialog
  777. PROPERTY_PROFILE_msNPAuthenticationType
  778. PROPERTY_PROFILE_msNPAllowedEapType
  779. */
  780. // authentication type
  781. VariantClear(&var);
  782. CHECK_HR(hr = m_SdoWrapper.GetProperty(PROPERTY_PROFILE_msNPAuthenticationType, &var));
  783. if(V_VT(&var) & VT_ARRAY)
  784. {
  785. m_dwArrayAuthenticationTypes = V_ARRAY(&var);
  786. m_dwAttributeFlags |= PABF_msNPAuthenticationType;
  787. }
  788. else
  789. m_dwArrayAuthenticationTypes.DeleteAll();
  790. // eap type
  791. VariantClear(&var);
  792. CHECK_HR(hr = m_SdoWrapper.GetProperty(PROPERTY_PROFILE_msNPAllowedEapType, &var));
  793. if(V_VT(&var) == VT_I4)
  794. {
  795. m_dwEapType = V_I4(&var);
  796. m_dwAttributeFlags |= PABF_msNPAllowedEapType;
  797. }
  798. else
  799. m_dwEapType = RAS_DEF_EAPTYPE;
  800. //=====================================
  801. // encryptioin
  802. /*
  803. // Encryption Dialog
  804. PROPERTY_PROFILE_msRASAllowEncryption
  805. PROPERTY_PROFILE_msRASEncryptionType
  806. */
  807. // encryption type
  808. VariantClear(&var);
  809. CHECK_HR(hr = m_SdoWrapper.GetProperty(PROPERTY_PROFILE_msRASEncryptionType, &var));
  810. if(V_VT(&var) == VT_I4)
  811. {
  812. m_dwEncryptionType = V_I4(&var);
  813. m_dwAttributeFlags |= PABF_msRASEncryptionType;
  814. }
  815. else
  816. m_dwEncryptionType = RAS_DEF_ENCRYPTIONTYPE;
  817. VariantClear(&var);
  818. CHECK_HR(hr = m_SdoWrapper.GetProperty(PROPERTY_PROFILE_msRASAllowEncryption, &var));
  819. if(V_VT(&var) == VT_I4)
  820. {
  821. m_dwEncryptionPolicy = V_I4(&var);
  822. m_dwAttributeFlags |= PABF_msRASAllowEncryption;
  823. }
  824. else
  825. m_dwEncryptionPolicy = RAS_DEF_ENCRYPTIONPOLICY;
  826. // specail code for error path
  827. L_ERR:
  828. VariantClear(&var);
  829. TRACE(_T("Leave CRASProfileMerge::Load()\r\n"));
  830. return hr;
  831. }
  832. //====================================================
  833. //
  834. // CRASProfile::Save
  835. //
  836. //
  837. HRESULT CRASProfileMerge::Save()
  838. {
  839. TRACE(_T("Enter CRASProfileMerge::Save()\r\n"));
  840. // ==
  841. ASSERT(m_spIProfile.p);
  842. ASSERT(m_spIDictionary.p);
  843. VARIANT var;
  844. HRESULT hr = S_OK;
  845. VariantInit(&var);
  846. USES_CONVERSION;
  847. //==================================================
  848. // constraints dialog
  849. /*
  850. // Constraints Dialog
  851. PROPERTY_PROFILE_msNPTimeOfDay
  852. PROPERTY_PROFILE_msNPCalledStationId
  853. PROPERTY_PROFILE_msNPAllowedPortTypes
  854. PROPERTY_PROFILE_msRADIUSIdleTimeout
  855. PROPERTY_PROFILE_msRADIUSSessionTimeout
  856. */
  857. // idleTimeout
  858. if (m_dwAttributeFlags & PABF_msRADIUSIdleTimeout)
  859. {
  860. VariantClear(&var);
  861. V_VT(&var) = VT_I4;
  862. V_I4(&var) = m_dwIdleTimeout;
  863. CHECK_HR(hr = m_SdoWrapper.PutProperty(PROPERTY_PROFILE_msRADIUSIdleTimeout, &var));
  864. }
  865. else
  866. CHECK_HR(hr = m_SdoWrapper.RemoveProperty(PROPERTY_PROFILE_msRADIUSIdleTimeout));
  867. // sessionTimeout
  868. if (m_dwAttributeFlags & PABF_msRADIUSSessionTimeout)
  869. {
  870. VariantClear(&var);
  871. V_VT(&var) = VT_I4;
  872. V_I4(&var) = m_dwSessionTimeout;
  873. CHECK_HR(hr = m_SdoWrapper.PutProperty(PROPERTY_PROFILE_msRADIUSSessionTimeout, &var));
  874. }
  875. else
  876. CHECK_HR(hr = m_SdoWrapper.RemoveProperty(PROPERTY_PROFILE_msRADIUSSessionTimeout));
  877. // timeOfDay -- multivalue
  878. if (m_dwAttributeFlags & PABF_msNPTimeOfDay)
  879. {
  880. VariantClear(&var);
  881. V_VT(&var) = VT_VARIANT | VT_ARRAY;
  882. V_ARRAY(&var) = (SAFEARRAY*)m_strArrayTimeOfDay;
  883. CHECK_HR(hr = m_SdoWrapper.PutProperty(PROPERTY_PROFILE_msNPTimeOfDay, &var));
  884. }
  885. else
  886. CHECK_HR(hr = m_SdoWrapper.RemoveProperty(PROPERTY_PROFILE_msNPTimeOfDay));
  887. // calledStationId -- multivalue
  888. if (m_dwAttributeFlags & PABF_msNPCalledStationId)
  889. {
  890. VariantClear(&var);
  891. V_VT(&var) = VT_VARIANT | VT_ARRAY;
  892. V_ARRAY(&var) = (SAFEARRAY*)m_strArrayCalledStationId;
  893. CHECK_HR(hr = m_SdoWrapper.PutProperty(PROPERTY_PROFILE_msNPCalledStationId, &var));
  894. }
  895. else
  896. CHECK_HR(hr = m_SdoWrapper.RemoveProperty(PROPERTY_PROFILE_msNPCalledStationId));
  897. // allowedPortTypes
  898. if (m_dwAttributeFlags & PABF_msNPAllowedPortTypes)
  899. {
  900. VariantClear(&var);
  901. V_VT(&var) = VT_VARIANT | VT_ARRAY;
  902. V_ARRAY(&var) = (SAFEARRAY*)m_dwArrayAllowedPortTypes;
  903. CHECK_HR(hr = m_SdoWrapper.PutProperty(PROPERTY_PROFILE_msNPAllowedPortTypes, &var));
  904. }
  905. else
  906. CHECK_HR(hr = m_SdoWrapper.RemoveProperty(PROPERTY_PROFILE_msNPAllowedPortTypes));
  907. //==================================
  908. // authentication
  909. /*
  910. // Authentication Dialog
  911. PROPERTY_PROFILE_msNPAuthenticationType
  912. PROPERTY_PROFILE_msNPAllowedEapType
  913. */
  914. // authentication type -- must
  915. VariantClear(&var);
  916. if (m_dwAttributeFlags & PABF_msNPAuthenticationType)
  917. {
  918. VariantClear(&var);
  919. V_VT(&var) = VT_VARIANT | VT_ARRAY;
  920. V_ARRAY(&var) = (SAFEARRAY*)m_dwArrayAuthenticationTypes;
  921. CHECK_HR(hr = m_SdoWrapper.PutProperty(PROPERTY_PROFILE_msNPAuthenticationType, &var));
  922. }
  923. else
  924. {
  925. CHECK_HR(hr = m_SdoWrapper.RemoveProperty(PROPERTY_PROFILE_msNPAllowedEapType));
  926. }
  927. if(m_dwArrayAuthenticationTypes.Find(RAS_AT_EAP) != -1)
  928. {
  929. VariantClear(&var);
  930. V_VT(&var) = VT_I4;
  931. V_I4(&var) = m_dwEapType;
  932. CHECK_HR(hr = m_SdoWrapper.PutProperty(PROPERTY_PROFILE_msNPAllowedEapType, &var));
  933. }
  934. else
  935. CHECK_HR(hr = m_SdoWrapper.RemoveProperty(PROPERTY_PROFILE_msNPAllowedEapType));
  936. //=====================================
  937. // encryptioin
  938. /*
  939. // Encryption Dialog
  940. PROPERTY_PROFILE_msRASAllowEncryption
  941. PROPERTY_PROFILE_msRASEncryptionType
  942. */
  943. // encryption type -- must
  944. if (m_dwAttributeFlags & PABF_msRASEncryptionType)
  945. {
  946. VariantClear(&var);
  947. V_VT(&var) = VT_I4;
  948. V_I4(&var) = m_dwEncryptionType;
  949. CHECK_HR(hr = m_SdoWrapper.PutProperty(PROPERTY_PROFILE_msRASEncryptionType, &var));
  950. }
  951. else
  952. {
  953. CHECK_HR(hr = m_SdoWrapper.RemoveProperty(PROPERTY_PROFILE_msRASEncryptionType));
  954. }
  955. if (m_dwAttributeFlags & PABF_msRASAllowEncryption)
  956. {
  957. VariantClear(&var);
  958. V_VT(&var) = VT_I4;
  959. V_I4(&var) = m_dwEncryptionPolicy;
  960. CHECK_HR(hr = m_SdoWrapper.PutProperty(PROPERTY_PROFILE_msRASAllowEncryption, &var));
  961. }
  962. else
  963. {
  964. CHECK_HR(hr = m_SdoWrapper.RemoveProperty(PROPERTY_PROFILE_msRASAllowEncryption));
  965. }
  966. //=====================================
  967. // networking
  968. /*
  969. // Networking Dialog
  970. PROPERTY_PROFILE_msRADIUSFramedIPAddress
  971. */
  972. // framedIPAddress -- ip address assignment poilcy, must
  973. if (m_dwAttributeFlags & PABF_msRADIUSFramedIPAddress)
  974. {
  975. VariantClear(&var);
  976. V_VT(&var) = VT_I4;
  977. V_I4(&var) = m_dwFramedIPAddress;
  978. CHECK_HR(hr = m_SdoWrapper.PutProperty(PROPERTY_PROFILE_msRADIUSFramedIPAddress, &var));
  979. }
  980. else
  981. CHECK_HR(hr = m_SdoWrapper.RemoveProperty(PROPERTY_PROFILE_msRADIUSFramedIPAddress));
  982. // RAS filter
  983. if ((BSTR)m_cbstrFilters && m_nFiltersSize > 0)
  984. {
  985. VariantClear(&var);
  986. #ifdef FILTERS_AS_BSTR
  987. V_VT(&var) = VT_BSTR;
  988. V_BSTR(&var) = (BSTR)m_cbstrFilters;
  989. #else // SAFEARRAY OF UI1
  990. {
  991. CBYTEArray ba;
  992. ba.AssignBlob((PBYTE)(BSTR)m_cbstrFilters, m_nFiltersSize);
  993. V_VT(&var) = VT_ARRAY | VT_UI1;
  994. V_ARRAY(&var) = (SAFEARRAY*)ba;
  995. }
  996. #endif
  997. CHECK_HR(hr = m_SdoWrapper.PutProperty(PROPERTY_PROFILE_msRASFilter, &var));
  998. VariantInit(&var); // the CBSTR will clean the memory
  999. }
  1000. else
  1001. CHECK_HR(hr = m_SdoWrapper.RemoveProperty(PROPERTY_PROFILE_msRASFilter));
  1002. //=====================================
  1003. // multilink
  1004. /*
  1005. // Multilink Dialog
  1006. PROPERTY_PROFILE_msRADIUSPortLimit
  1007. PROPERTY_PROFILE_msRASBapLinednLimit
  1008. PROPERTY_PROFILE_msRASBapLinednTime
  1009. PROPERTY_PROFILE_msRASBapRequired
  1010. */
  1011. //port limit
  1012. if (m_dwAttributeFlags & PABF_msRADIUSPortLimit)
  1013. {
  1014. VariantClear(&var);
  1015. V_VT(&var) = VT_I4;
  1016. V_I4(&var) = m_dwPortLimit;
  1017. CHECK_HR(hr = m_SdoWrapper.PutProperty(PROPERTY_PROFILE_msRADIUSPortLimit, &var));
  1018. }
  1019. else
  1020. CHECK_HR(hr = m_SdoWrapper.RemoveProperty(PROPERTY_PROFILE_msRADIUSPortLimit));
  1021. // BAP
  1022. if (m_dwAttributeFlags & PABF_msRASBapRequired)
  1023. {
  1024. VariantClear(&var);
  1025. V_VT(&var) = VT_I4;
  1026. V_I4(&var) = m_dwBapRequired;
  1027. CHECK_HR(hr = m_SdoWrapper.PutProperty(PROPERTY_PROFILE_msRASBapRequired, &var));
  1028. }
  1029. else
  1030. {
  1031. CHECK_HR(hr = m_SdoWrapper.RemoveProperty(PROPERTY_PROFILE_msRASBapRequired));
  1032. }
  1033. // line down limit
  1034. if (m_dwAttributeFlags & PABF_msRASBapLinednLimit)
  1035. {
  1036. VariantClear(&var);
  1037. V_VT(&var) = VT_I4;
  1038. V_I4(&var) = m_dwBapLineDnLimit;
  1039. CHECK_HR(hr = m_SdoWrapper.PutProperty(PROPERTY_PROFILE_msRASBapLinednLimit, &var));
  1040. }
  1041. else
  1042. {
  1043. CHECK_HR(hr = m_SdoWrapper.RemoveProperty(PROPERTY_PROFILE_msRASBapLinednLimit));
  1044. }
  1045. // line down time
  1046. if (m_dwAttributeFlags & PABF_msRASBapLinednTime)
  1047. {
  1048. VariantClear(&var);
  1049. V_VT(&var) = VT_I4;
  1050. V_I4(&var) = m_dwBapLineDnTime;
  1051. CHECK_HR(hr = m_SdoWrapper.PutProperty(PROPERTY_PROFILE_msRASBapLinednTime, &var));
  1052. }
  1053. else
  1054. {
  1055. CHECK_HR(hr = m_SdoWrapper.RemoveProperty(PROPERTY_PROFILE_msRASBapLinednTime));
  1056. }
  1057. // specail code for error path
  1058. L_ERR:
  1059. VariantClear(&var);
  1060. TRACE(_T("Leave CRASProfileMerge::Save()\r\n"));
  1061. return hr;
  1062. }