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.

2429 lines
53 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
  4. /**********************************************************************/
  5. /*
  6. spddb.h
  7. FILE HISTORY:
  8. */
  9. #include "stdafx.h"
  10. #include "DynamLnk.h"
  11. #include "spddb.h"
  12. #include "spdutil.h"
  13. #include "security.h"
  14. #include "lm.h"
  15. #include "service.h"
  16. #define AVG_PREFERRED_ENUM_COUNT 40
  17. #define DEFAULT_SECURITY_PKG _T("negotiate")
  18. #define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
  19. #define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
  20. // internal functions
  21. BOOL IsUserAdmin(LPCTSTR pszMachine, PSID AccountSid);
  22. BOOL LookupAliasFromRid(LPWSTR TargetComputer, DWORD Rid, LPWSTR Name, PDWORD cchName);
  23. DWORD ValidateDomainAccount(IN CString Machine, IN CString UserName, IN CString Domain, OUT PSID * AccountSid);
  24. NTSTATUS ValidatePassword(IN LPCWSTR UserName, IN LPCWSTR Domain, IN LPCWSTR Password);
  25. DWORD GetCurrentUser(CString & strAccount);
  26. template <class T>
  27. void
  28. FreeItemsAndEmptyArray (
  29. T& array)
  30. {
  31. for (int i = 0; i < array.GetSize(); i++)
  32. {
  33. delete array.GetAt(i);
  34. }
  35. array.RemoveAll();
  36. }
  37. DWORD GetCurrentUser(CString & strAccount)
  38. {
  39. LPBYTE pBuf;
  40. NET_API_STATUS status = NetWkstaUserGetInfo(NULL, 1, &pBuf);
  41. if (status == NERR_Success)
  42. {
  43. strAccount.Empty();
  44. WKSTA_USER_INFO_1 * pwkstaUserInfo = (WKSTA_USER_INFO_1 *) pBuf;
  45. strAccount = pwkstaUserInfo->wkui1_logon_domain;
  46. strAccount += _T("\\");
  47. strAccount += pwkstaUserInfo->wkui1_username;
  48. NetApiBufferFree(pBuf);
  49. }
  50. return (DWORD) status;
  51. }
  52. /*!--------------------------------------------------------------------------
  53. IsAdmin
  54. Connect to the remote machine as administrator with user-supplied
  55. credentials to see if the user has admin priviledges
  56. Returns
  57. TRUE - the user has admin rights
  58. FALSE - if user doesn't
  59. Author: EricDav, KennT
  60. ---------------------------------------------------------------------------*/
  61. DWORD IsAdmin(LPCTSTR szMachineName, LPCTSTR szAccount, LPCTSTR szPassword, BOOL * pIsAdmin)
  62. {
  63. CString stAccount;
  64. CString stDomain;
  65. CString stUser;
  66. CString stMachineName;
  67. DWORD dwStatus;
  68. BOOL fIsAdmin = FALSE;
  69. // get the current user info
  70. if (szAccount == NULL)
  71. {
  72. GetCurrentUser(stAccount);
  73. }
  74. else
  75. {
  76. stAccount = szAccount;
  77. }
  78. // separate the user and domain
  79. int nPos = stAccount.Find(_T("\\"));
  80. stDomain = stAccount.Left(nPos);
  81. stUser = stAccount.Right(stAccount.GetLength() - nPos - 1);
  82. // build the machine string
  83. stMachineName = szMachineName;
  84. if ( stMachineName.Left(2) != TEXT( "\\\\" ) )
  85. {
  86. stMachineName = TEXT( "\\\\" ) + stMachineName;
  87. }
  88. // validate the domain account and get the sid
  89. PSID connectSid;
  90. dwStatus = ValidateDomainAccount( stMachineName, stUser, stDomain, &connectSid );
  91. if ( dwStatus != ERROR_SUCCESS )
  92. {
  93. goto Error;
  94. }
  95. // if a password was supplied, is it correct?
  96. if (szPassword)
  97. {
  98. dwStatus = ValidatePassword( stUser, stDomain, szPassword );
  99. if ( dwStatus != SEC_E_OK )
  100. {
  101. switch ( dwStatus )
  102. {
  103. case SEC_E_LOGON_DENIED:
  104. dwStatus = ERROR_INVALID_PASSWORD;
  105. break;
  106. case SEC_E_INVALID_HANDLE:
  107. dwStatus = ERROR_INTERNAL_ERROR;
  108. break;
  109. default:
  110. dwStatus = ERROR_INTERNAL_ERROR;
  111. break;
  112. } // end of switch
  113. goto Error;
  114. } // Did ValidatePassword succeed?
  115. }
  116. // now check the machine to see if this account has admin access
  117. fIsAdmin = IsUserAdmin( stMachineName, connectSid );
  118. Error:
  119. if (pIsAdmin)
  120. *pIsAdmin = fIsAdmin;
  121. return dwStatus;
  122. }
  123. BOOL
  124. IsUserAdmin(LPCTSTR pszMachine,
  125. PSID AccountSid)
  126. /*++
  127. Routine Description:
  128. Determine if the specified account is a member of the local admin's group
  129. Arguments:
  130. AccountSid - pointer to service account Sid
  131. Return Value:
  132. True if member
  133. --*/
  134. {
  135. NET_API_STATUS status;
  136. DWORD count;
  137. WCHAR adminGroupName[UNLEN+1];
  138. DWORD cchName = UNLEN;
  139. PLOCALGROUP_MEMBERS_INFO_0 grpMemberInfo;
  140. PLOCALGROUP_MEMBERS_INFO_0 pInfo;
  141. DWORD entriesRead;
  142. DWORD totalEntries;
  143. DWORD_PTR resumeHandle = NULL;
  144. DWORD bufferSize = 128;
  145. BOOL foundEntry = FALSE;
  146. // get the name of the admin's group
  147. if (!LookupAliasFromRid(NULL,
  148. DOMAIN_ALIAS_RID_ADMINS,
  149. adminGroupName,
  150. &cchName)) {
  151. return(FALSE);
  152. }
  153. // get the Sids of the members of the admin's group
  154. do
  155. {
  156. status = NetLocalGroupGetMembers(pszMachine,
  157. adminGroupName,
  158. 0, // level 0 - just the Sid
  159. (LPBYTE *)&grpMemberInfo,
  160. bufferSize,
  161. &entriesRead,
  162. &totalEntries,
  163. &resumeHandle);
  164. bufferSize *= 2;
  165. if ( status == ERROR_MORE_DATA )
  166. {
  167. // we got some of the data but I want it all; free this buffer and
  168. // reset the context handle for the API
  169. NetApiBufferFree( grpMemberInfo );
  170. resumeHandle = NULL;
  171. }
  172. } while ( status == NERR_BufTooSmall || status == ERROR_MORE_DATA );
  173. if ( status == NERR_Success )
  174. {
  175. // loop through the members of the admin group, comparing the supplied
  176. // Sid to that of the group members' Sids
  177. for ( count = 0, pInfo = grpMemberInfo; count < totalEntries; ++count, ++pInfo )
  178. {
  179. if ( EqualSid( AccountSid, pInfo->lgrmi0_sid ))
  180. {
  181. foundEntry = TRUE;
  182. break;
  183. }
  184. }
  185. NetApiBufferFree( grpMemberInfo );
  186. }
  187. return foundEntry;
  188. }
  189. //
  190. //
  191. //
  192. BOOL
  193. LookupAliasFromRid(
  194. LPWSTR TargetComputer,
  195. DWORD Rid,
  196. LPWSTR Name,
  197. PDWORD cchName
  198. )
  199. {
  200. SID_IDENTIFIER_AUTHORITY sia = SECURITY_NT_AUTHORITY;
  201. SID_NAME_USE snu;
  202. PSID pSid;
  203. WCHAR DomainName[DNLEN+1];
  204. DWORD cchDomainName = DNLEN;
  205. BOOL bSuccess = FALSE;
  206. //
  207. // Sid is the same regardless of machine, since the well-known
  208. // BUILTIN domain is referenced.
  209. //
  210. if(AllocateAndInitializeSid(&sia,
  211. 2,
  212. SECURITY_BUILTIN_DOMAIN_RID,
  213. Rid,
  214. 0, 0, 0, 0, 0, 0,
  215. &pSid)) {
  216. bSuccess = LookupAccountSidW(TargetComputer,
  217. pSid,
  218. Name,
  219. cchName,
  220. DomainName,
  221. &cchDomainName,
  222. &snu);
  223. FreeSid(pSid);
  224. }
  225. return bSuccess;
  226. } // LookupAliasFromRid
  227. DWORD
  228. ValidateDomainAccount(
  229. IN CString Machine,
  230. IN CString UserName,
  231. IN CString Domain,
  232. OUT PSID * AccountSid
  233. )
  234. /*++
  235. Routine Description:
  236. For the given credentials, look up the account SID for the specified
  237. domain. As a side effect, the Sid is stored in theData->m_Sid.
  238. Arguments:
  239. pointers to strings that describe the user name, domain name, and password
  240. AccountSid - address of pointer that receives the SID for this user
  241. Return Value:
  242. TRUE if everything validated ok.
  243. --*/
  244. {
  245. DWORD dwStatus = ERROR_SUCCESS;
  246. DWORD dwSidSize = 128;
  247. DWORD dwDomainNameSize = 128;
  248. LPWSTR pwszDomainName;
  249. SID_NAME_USE SidType;
  250. CString domainAccount;
  251. PSID accountSid;
  252. domainAccount = Domain + _T("\\") + UserName;
  253. do {
  254. // Attempt to allocate a buffer for the SID. Note that apparently in the
  255. // absence of any error theData->m_Sid is freed only when theData goes
  256. // out of scope.
  257. accountSid = LocalAlloc( LMEM_FIXED, dwSidSize );
  258. pwszDomainName = (LPWSTR) LocalAlloc( LMEM_FIXED, dwDomainNameSize * sizeof(WCHAR) );
  259. // Was space allocated for the SID and domain name successfully?
  260. if ( accountSid == NULL || pwszDomainName == NULL ) {
  261. if ( accountSid != NULL ) {
  262. LocalFree( accountSid );
  263. }
  264. if ( pwszDomainName != NULL ) {
  265. LocalFree( pwszDomainName );
  266. }
  267. //FATALERR( IDS_ERR_NOT_ENOUGH_MEMORY, GetLastError() ); // no return
  268. break;
  269. }
  270. // Attempt to Retrieve the SID and domain name. If LookupAccountName failes
  271. // because of insufficient buffer size(s) dwSidSize and dwDomainNameSize
  272. // will be set correctly for the next attempt.
  273. if ( !LookupAccountName( Machine,
  274. domainAccount,
  275. accountSid,
  276. &dwSidSize,
  277. pwszDomainName,
  278. &dwDomainNameSize,
  279. &SidType ))
  280. {
  281. // free the Sid buffer and find out why we failed
  282. LocalFree( accountSid );
  283. dwStatus = GetLastError();
  284. }
  285. // domain name isn't needed at any time
  286. LocalFree( pwszDomainName );
  287. pwszDomainName = NULL;
  288. } while ( dwStatus == ERROR_INSUFFICIENT_BUFFER );
  289. if ( dwStatus == ERROR_SUCCESS ) {
  290. *AccountSid = accountSid;
  291. }
  292. return dwStatus;
  293. } // ValidateDomainAccount
  294. NTSTATUS
  295. ValidatePassword(
  296. IN LPCWSTR UserName,
  297. IN LPCWSTR Domain,
  298. IN LPCWSTR Password
  299. )
  300. /*++
  301. Routine Description:
  302. Uses SSPI to validate the specified password
  303. Arguments:
  304. UserName - Supplies the user name
  305. Domain - Supplies the user's domain
  306. Password - Supplies the password
  307. Return Value:
  308. TRUE if the password is valid.
  309. FALSE otherwise.
  310. --*/
  311. {
  312. SECURITY_STATUS SecStatus;
  313. SECURITY_STATUS AcceptStatus;
  314. SECURITY_STATUS InitStatus;
  315. CredHandle ClientCredHandle;
  316. CredHandle ServerCredHandle;
  317. BOOL ClientCredAllocated = FALSE;
  318. BOOL ServerCredAllocated = FALSE;
  319. CtxtHandle ClientContextHandle;
  320. CtxtHandle ServerContextHandle;
  321. TimeStamp Lifetime;
  322. ULONG ContextAttributes;
  323. PSecPkgInfo PackageInfo = NULL;
  324. ULONG ClientFlags;
  325. ULONG ServerFlags;
  326. SEC_WINNT_AUTH_IDENTITY_W AuthIdentity;
  327. SecBufferDesc NegotiateDesc;
  328. SecBuffer NegotiateBuffer;
  329. SecBufferDesc ChallengeDesc;
  330. SecBuffer ChallengeBuffer;
  331. SecBufferDesc AuthenticateDesc;
  332. SecBuffer AuthenticateBuffer;
  333. SecBufferDesc *pChallengeDesc = NULL;
  334. CtxtHandle * pClientContextHandle = NULL;
  335. CtxtHandle * pServerContextHandle = NULL;
  336. AuthIdentity.User = (LPWSTR)UserName;
  337. AuthIdentity.UserLength = lstrlenW(UserName);
  338. AuthIdentity.Domain = (LPWSTR)Domain;
  339. AuthIdentity.DomainLength = lstrlenW(Domain);
  340. AuthIdentity.Password = (LPWSTR)Password;
  341. AuthIdentity.PasswordLength = lstrlenW(Password);
  342. AuthIdentity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
  343. NegotiateBuffer.pvBuffer = NULL;
  344. ChallengeBuffer.pvBuffer = NULL;
  345. AuthenticateBuffer.pvBuffer = NULL;
  346. //
  347. // Get info about the security packages.
  348. //
  349. SecStatus = QuerySecurityPackageInfo( DEFAULT_SECURITY_PKG, &PackageInfo );
  350. if ( SecStatus != STATUS_SUCCESS ) {
  351. goto error_exit;
  352. }
  353. //
  354. // Acquire a credential handle for the server side
  355. //
  356. SecStatus = AcquireCredentialsHandle(
  357. NULL,
  358. DEFAULT_SECURITY_PKG,
  359. SECPKG_CRED_INBOUND,
  360. NULL,
  361. &AuthIdentity,
  362. NULL,
  363. NULL,
  364. &ServerCredHandle,
  365. &Lifetime );
  366. if ( SecStatus != STATUS_SUCCESS ) {
  367. goto error_exit;
  368. }
  369. ServerCredAllocated = TRUE;
  370. //
  371. // Acquire a credential handle for the client side
  372. //
  373. SecStatus = AcquireCredentialsHandle(
  374. NULL, // New principal
  375. DEFAULT_SECURITY_PKG,
  376. SECPKG_CRED_OUTBOUND,
  377. NULL,
  378. &AuthIdentity,
  379. NULL,
  380. NULL,
  381. &ClientCredHandle,
  382. &Lifetime );
  383. if ( SecStatus != STATUS_SUCCESS ) {
  384. goto error_exit;
  385. }
  386. ClientCredAllocated = TRUE;
  387. NegotiateBuffer.pvBuffer = LocalAlloc( 0, PackageInfo->cbMaxToken ); // [CHKCHK] check or allocate this earlier //
  388. if ( NegotiateBuffer.pvBuffer == NULL ) {
  389. SecStatus = SEC_E_INSUFFICIENT_MEMORY;
  390. goto error_exit;
  391. }
  392. ChallengeBuffer.pvBuffer = LocalAlloc( 0, PackageInfo->cbMaxToken ); // [CHKCHK]
  393. if ( ChallengeBuffer.pvBuffer == NULL ) {
  394. SecStatus = SEC_E_INSUFFICIENT_MEMORY;
  395. goto error_exit;
  396. }
  397. do {
  398. //
  399. // Get the NegotiateMessage (ClientSide)
  400. //
  401. NegotiateDesc.ulVersion = 0;
  402. NegotiateDesc.cBuffers = 1;
  403. NegotiateDesc.pBuffers = &NegotiateBuffer;
  404. NegotiateBuffer.BufferType = SECBUFFER_TOKEN;
  405. NegotiateBuffer.cbBuffer = PackageInfo->cbMaxToken;
  406. ClientFlags = 0; // ISC_REQ_MUTUAL_AUTH | ISC_REQ_REPLAY_DETECT; // [CHKCHK] 0
  407. InitStatus = InitializeSecurityContext(
  408. &ClientCredHandle,
  409. pClientContextHandle, // (NULL on the first pass, partially formed ctx on the next)
  410. NULL, // [CHKCHK] szTargetName
  411. ClientFlags,
  412. 0, // Reserved 1
  413. SECURITY_NATIVE_DREP,
  414. pChallengeDesc, // (NULL on the first pass)
  415. 0, // Reserved 2
  416. &ClientContextHandle,
  417. &NegotiateDesc,
  418. &ContextAttributes,
  419. &Lifetime );
  420. // BUGBUG - the following call to NT_SUCCESS should be replaced with something.
  421. if ( !NT_SUCCESS(InitStatus) ) {
  422. SecStatus = InitStatus;
  423. goto error_exit;
  424. }
  425. // ValidateBuffer( &NegotiateDesc ) // [CHKCHK]
  426. pClientContextHandle = &ClientContextHandle;
  427. //
  428. // Get the ChallengeMessage (ServerSide)
  429. //
  430. NegotiateBuffer.BufferType |= SECBUFFER_READONLY;
  431. ChallengeDesc.ulVersion = 0;
  432. ChallengeDesc.cBuffers = 1;
  433. ChallengeDesc.pBuffers = &ChallengeBuffer;
  434. ChallengeBuffer.cbBuffer = PackageInfo->cbMaxToken;
  435. ChallengeBuffer.BufferType = SECBUFFER_TOKEN;
  436. ServerFlags = ASC_REQ_ALLOW_NON_USER_LOGONS; // ASC_REQ_EXTENDED_ERROR; [CHKCHK]
  437. AcceptStatus = AcceptSecurityContext(
  438. &ServerCredHandle,
  439. pServerContextHandle, // (NULL on the first pass)
  440. &NegotiateDesc,
  441. ServerFlags,
  442. SECURITY_NATIVE_DREP,
  443. &ServerContextHandle,
  444. &ChallengeDesc,
  445. &ContextAttributes,
  446. &Lifetime );
  447. // BUGBUG - the following call to NT_SUCCESS should be replaced with something.
  448. if ( !NT_SUCCESS(AcceptStatus) ) {
  449. SecStatus = AcceptStatus;
  450. goto error_exit;
  451. }
  452. // ValidateBuffer( &NegotiateDesc ) // [CHKCHK]
  453. pChallengeDesc = &ChallengeDesc;
  454. pServerContextHandle = &ServerContextHandle;
  455. } while ( AcceptStatus == SEC_I_CONTINUE_NEEDED ); // || InitStatus == SEC_I_CONTINUE_NEEDED );
  456. error_exit:
  457. if (ServerCredAllocated) {
  458. FreeCredentialsHandle( &ServerCredHandle );
  459. }
  460. if (ClientCredAllocated) {
  461. FreeCredentialsHandle( &ClientCredHandle );
  462. }
  463. //
  464. // Final Cleanup
  465. //
  466. if ( NegotiateBuffer.pvBuffer != NULL ) {
  467. (VOID) LocalFree( NegotiateBuffer.pvBuffer );
  468. }
  469. if ( ChallengeBuffer.pvBuffer != NULL ) {
  470. (VOID) LocalFree( ChallengeBuffer.pvBuffer );
  471. }
  472. if ( AuthenticateBuffer.pvBuffer != NULL ) {
  473. (VOID) LocalFree( AuthenticateBuffer.pvBuffer );
  474. }
  475. return(SecStatus);
  476. } // ValidatePassword
  477. DEBUG_DECLARE_INSTANCE_COUNTER(CSpdInfo);
  478. CSpdInfo::CSpdInfo() :
  479. m_cRef(1)
  480. {
  481. m_Init=0;
  482. m_Active=0;
  483. DEBUG_INCREMENT_INSTANCE_COUNTER(CSpdInfo);
  484. }
  485. CSpdInfo::~CSpdInfo()
  486. {
  487. DEBUG_DECREMENT_INSTANCE_COUNTER(CSpdInfo);
  488. CSingleLock cLock(&m_csData);
  489. cLock.Lock();
  490. //Convert the data to our internal data structure
  491. FreeItemsAndEmptyArray(m_arrayFilters);
  492. FreeItemsAndEmptyArray(m_arraySpecificFilters);
  493. FreeItemsAndEmptyArray(m_arrayMmFilters);
  494. FreeItemsAndEmptyArray(m_arrayMmSpecificFilters);
  495. FreeItemsAndEmptyArray(m_arrayMmPolicies);
  496. FreeItemsAndEmptyArray(m_arrMmAuthMethods);
  497. FreeItemsAndEmptyArray(m_arrayMmSAs);
  498. FreeItemsAndEmptyArray(m_arrayQmSAs);
  499. FreeItemsAndEmptyArray(m_arrayQmPolicies);
  500. cLock.Unlock();
  501. }
  502. // Although this object is not a COM Interface, we want to be able to
  503. // take advantage of recounting, so we have basic addref/release/QI support
  504. IMPLEMENT_ADDREF_RELEASE(CSpdInfo)
  505. IMPLEMENT_SIMPLE_QUERYINTERFACE(CSpdInfo, ISpdInfo)
  506. HRESULT CSpdInfo::SetComputerName(LPTSTR pszName)
  507. {
  508. m_stMachineName = pszName;
  509. return S_OK;
  510. }
  511. HRESULT CSpdInfo::GetComputerName(CString * pstName)
  512. {
  513. Assert(pstName);
  514. if (NULL == pstName)
  515. return E_INVALIDARG;
  516. *pstName = m_stMachineName;
  517. return S_OK;
  518. }
  519. //Call the SPD to enum policies and put it to our array
  520. HRESULT CSpdInfo::InternalEnumMmAuthMethods(
  521. CMmAuthMethodsArray * pArray,
  522. DWORD dwPreferredNum /* = 0 by default get all entries*/)
  523. {
  524. Assert(pArray);
  525. HRESULT hr = hrOK;
  526. PMM_AUTH_METHODS pAuths = NULL;
  527. DWORD dwNumAuths = 0;
  528. DWORD dwTemp = 0;
  529. DWORD dwResumeHandle = 0;
  530. FreeItemsAndEmptyArray(*pArray);
  531. do
  532. {
  533. dwTemp = 0;
  534. CWRg(::EnumMMAuthMethods(
  535. (LPTSTR)(LPCTSTR)m_stMachineName,
  536. &pAuths,
  537. dwPreferredNum,
  538. &dwTemp,
  539. &dwResumeHandle
  540. ));
  541. pArray->SetSize(dwNumAuths + dwTemp);
  542. for (int i = 0; i < (int)dwTemp; i++)
  543. {
  544. CMmAuthMethods * pAuth = new CMmAuthMethods;
  545. if (NULL == pAuth)
  546. {
  547. hr = E_OUTOFMEMORY;
  548. break;
  549. }
  550. *pAuth = *(pAuths + i);
  551. (*pArray)[dwNumAuths + i] = pAuth;
  552. }
  553. dwNumAuths += dwTemp;
  554. if (pAuths)
  555. {
  556. SPDApiBufferFree(pAuths);
  557. }
  558. }while (TRUE);
  559. // it will automatically break out from the loop when SPD returns ERROR_NO_DATA
  560. Error:
  561. //this particular error is because we don't have any data. Ignore it
  562. if (HRESULT_FROM_WIN32(ERROR_NO_DATA) == hr)
  563. hr = hrOK;
  564. return hr;
  565. }
  566. HRESULT CSpdInfo::EnumMmAuthMethods()
  567. {
  568. HRESULT hr = hrOK;
  569. int i;
  570. CSingleLock cLock(&m_csData);
  571. CMmAuthMethodsArray arrayTemp;
  572. CORg(InternalEnumMmAuthMethods(
  573. &arrayTemp
  574. ));
  575. cLock.Lock();
  576. FreeItemsAndEmptyArray(m_arrMmAuthMethods);
  577. m_arrMmAuthMethods.Copy(arrayTemp);
  578. Error:
  579. //this particular error is because we don't have any MM policies. Ignore it
  580. if (HRESULT_FROM_WIN32(ERROR_NO_DATA) == hr)
  581. hr = hrOK;
  582. return hr;
  583. }
  584. //Call the SPD to enum all Main mode SAs
  585. HRESULT CSpdInfo::InternalEnumMmSAs(
  586. CMmSAArray * pArray)
  587. {
  588. HRESULT hr = hrOK;
  589. PIPSEC_MM_SA pSAs = NULL;
  590. DWORD dwNumEntries = 10;
  591. DWORD dwTotal = 0;
  592. DWORD dwEnumHandle = 0;
  593. IPSEC_MM_SA MMTemplate;
  594. int i;
  595. FreeItemsAndEmptyArray(*pArray);
  596. memset(&MMTemplate,0,sizeof(IPSEC_MM_SA));
  597. DWORD dwNumSAs = 0;
  598. do
  599. {
  600. dwNumEntries = 10; //we request 10 (the Max#) SAs each time
  601. CWRg(::IPSecEnumMMSAs(
  602. (LPTSTR)(LPCTSTR)m_stMachineName,
  603. &MMTemplate,
  604. &pSAs,
  605. &dwNumEntries,
  606. &dwTotal,
  607. &dwEnumHandle,
  608. 0 //dwFlags
  609. ));
  610. pArray->SetSize(dwNumSAs + dwNumEntries);
  611. for (i = 0; i < (int)dwNumEntries; i++)
  612. {
  613. CMmSA * psa = new CMmSA;
  614. if (NULL == psa)
  615. {
  616. hr = E_OUTOFMEMORY;
  617. break;
  618. }
  619. *psa = *(pSAs + i);
  620. LoadMiscMmSAInfo(psa);
  621. (*pArray)[dwNumSAs + i] = psa;
  622. }
  623. dwNumSAs += dwNumEntries;
  624. if (pSAs)
  625. {
  626. SPDApiBufferFree(pSAs);
  627. }
  628. }while (dwTotal);
  629. Error:
  630. //this particular error is because we don't have any data. Ignore it
  631. if (HRESULT_FROM_WIN32(ERROR_NO_DATA) == hr)
  632. hr = hrOK;
  633. return hr;
  634. }
  635. HRESULT CSpdInfo::EnumMmSAs()
  636. {
  637. HRESULT hr = hrOK;
  638. int i;
  639. DWORD dwCurrentIndexType = 0;
  640. DWORD dwCurrentSortOption = 0;
  641. CSingleLock cLock(&m_csData);
  642. CMmSAArray arrayTemp;
  643. CORg(InternalEnumMmSAs(
  644. &arrayTemp
  645. ));
  646. cLock.Lock();
  647. FreeItemsAndEmptyArray(m_arrayMmSAs);
  648. m_arrayMmSAs.Copy(arrayTemp);
  649. //remember the original IndexType and Sort options
  650. dwCurrentIndexType = m_IndexMgrMmSAs.GetCurrentIndexType();
  651. dwCurrentSortOption = m_IndexMgrMmSAs.GetCurrentSortOption();
  652. m_IndexMgrMmSAs.Reset();
  653. for (i = 0; i < (int)m_arrayMmSAs.GetSize(); i++)
  654. {
  655. m_IndexMgrMmSAs.AddItem(m_arrayMmSAs.GetAt(i));
  656. }
  657. m_IndexMgrMmSAs.Sort(dwCurrentIndexType, dwCurrentSortOption);
  658. Error:
  659. //this particular error is because we don't have any MM policies. Ignore it
  660. if (HRESULT_FROM_WIN32(ERROR_NO_DATA) == hr)
  661. hr = hrOK;
  662. return hr;
  663. }
  664. //Call the SPD to enum all Quick mode SAs
  665. HRESULT CSpdInfo::InternalEnumQmSAs(
  666. CQmSAArray * pArray)
  667. {
  668. HRESULT hr = hrOK;
  669. PIPSEC_QM_SA pSAs = NULL;
  670. DWORD dwNumEntries = 10;
  671. DWORD dwTotal = 0;
  672. DWORD dwResumeHandle = 0;
  673. int i;
  674. FreeItemsAndEmptyArray(*pArray);
  675. DWORD dwNumSAs = 0;
  676. do
  677. {
  678. CWRg(::EnumQMSAs(
  679. (LPTSTR)(LPCTSTR)m_stMachineName,
  680. NULL, //pMMTemplate
  681. &pSAs,
  682. 0, //We prefer to get all
  683. &dwNumEntries,
  684. &dwTotal,
  685. &dwResumeHandle,
  686. 0 //dwFlags
  687. ));
  688. pArray->SetSize(dwNumSAs + dwNumEntries);
  689. for (i = 0; i < (int)dwNumEntries; i++)
  690. {
  691. Assert(pSAs);
  692. CQmSA * psa = new CQmSA;
  693. if (NULL == psa)
  694. {
  695. hr = E_OUTOFMEMORY;
  696. break;
  697. }
  698. *psa = *(pSAs + i);
  699. LoadMiscQmSAInfo(psa);
  700. (*pArray)[dwNumSAs + i] = psa;
  701. }
  702. dwNumSAs += dwNumEntries;
  703. if (pSAs)
  704. {
  705. SPDApiBufferFree(pSAs);
  706. }
  707. }while (TRUE);
  708. Error:
  709. //this particular error is because we don't have any data. Ignore it
  710. if (HRESULT_FROM_WIN32(ERROR_NO_DATA) == hr)
  711. hr = hrOK;
  712. return hr;
  713. }
  714. HRESULT CSpdInfo::EnumQmSAs()
  715. {
  716. HRESULT hr = hrOK;
  717. int i;
  718. DWORD dwCurrentIndexType = 0;
  719. DWORD dwCurrentSortOption = 0;
  720. CSingleLock cLock(&m_csData);
  721. CQmSAArray arrayTemp;
  722. CORg(InternalEnumQmSAs(
  723. &arrayTemp
  724. ));
  725. cLock.Lock();
  726. FreeItemsAndEmptyArray(m_arrayQmSAs);
  727. m_arrayQmSAs.Copy(arrayTemp);
  728. //remember the original IndexType and Sort options
  729. dwCurrentIndexType = m_IndexMgrQmSAs.GetCurrentIndexType();
  730. dwCurrentSortOption = m_IndexMgrQmSAs.GetCurrentSortOption();
  731. m_IndexMgrQmSAs.Reset();
  732. for (i = 0; i < (int)m_arrayQmSAs.GetSize(); i++)
  733. {
  734. m_IndexMgrQmSAs.AddItem(m_arrayQmSAs.GetAt(i));
  735. }
  736. m_IndexMgrQmSAs.Sort(dwCurrentIndexType, dwCurrentSortOption);
  737. Error:
  738. return hr;
  739. }
  740. //Call the SPD to enum filters and put it to our array
  741. HRESULT CSpdInfo::InternalEnumMmFilters(
  742. DWORD dwLevel,
  743. GUID guid,
  744. CMmFilterInfoArray * pArray,
  745. DWORD dwPreferredNum /* = 0 by default get all entries*/)
  746. {
  747. Assert(pArray);
  748. HRESULT hr = hrOK;
  749. PMM_FILTER pFilters = NULL;
  750. DWORD dwNumFilters = 0;
  751. DWORD dwTemp = 0;
  752. DWORD dwResumeHandle = 0;
  753. FreeItemsAndEmptyArray(*pArray);
  754. do
  755. {
  756. dwTemp = 0;
  757. CWRg(::EnumMMFilters(
  758. (LPTSTR)(LPCTSTR)m_stMachineName,
  759. dwLevel,
  760. guid,
  761. &pFilters,
  762. dwPreferredNum,
  763. &dwTemp,
  764. &dwResumeHandle
  765. ));
  766. pArray->SetSize(dwNumFilters + dwTemp);
  767. for (int i = 0; i < (int)dwTemp; i++)
  768. {
  769. CMmFilterInfo * pFltr = new CMmFilterInfo;
  770. if (NULL == pFltr)
  771. {
  772. hr = E_OUTOFMEMORY;
  773. break;
  774. }
  775. *pFltr = *(pFilters + i);
  776. LoadMiscMmFilterInfo(pFltr);
  777. (*pArray)[dwNumFilters + i] = pFltr;
  778. }
  779. dwNumFilters += dwTemp;
  780. if (pFilters)
  781. {
  782. SPDApiBufferFree(pFilters);
  783. }
  784. }while (TRUE);
  785. // it will automatically break out from the loop when SPD returns ERROR_NO_DATA
  786. Error:
  787. //this particular error is because we don't have any data. Ignore it
  788. if (HRESULT_FROM_WIN32(ERROR_NO_DATA) == hr)
  789. hr = hrOK;
  790. return hr;
  791. }
  792. HRESULT CSpdInfo::EnumMmFilters()
  793. {
  794. HRESULT hr = S_OK;
  795. int i;
  796. DWORD dwCurrentIndexType = 0;
  797. DWORD dwCurrentSortOption = 0;
  798. CSingleLock cLock(&m_csData);
  799. //TODO we should either read all filters in one short
  800. // or create some assync way to query filters
  801. GUID guid;
  802. ZeroMemory(&guid, sizeof(guid));
  803. CMmFilterInfoArray arrayTempGeneric;
  804. CMmFilterInfoArray arrayTempSpecific;
  805. CORg(InternalEnumMmFilters(
  806. ENUM_GENERIC_FILTERS,
  807. guid,
  808. &arrayTempGeneric
  809. ));
  810. //Load the specific filters
  811. CORg(InternalEnumMmFilters(
  812. ENUM_SPECIFIC_FILTERS,
  813. guid,
  814. &arrayTempSpecific
  815. ));
  816. cLock.Lock();
  817. FreeItemsAndEmptyArray(m_arrayMmFilters);
  818. m_arrayMmFilters.Copy(arrayTempGeneric);
  819. FreeItemsAndEmptyArray(m_arrayMmSpecificFilters);
  820. m_arrayMmSpecificFilters.Copy(arrayTempSpecific);
  821. //remember the original IndexType and Sort options
  822. dwCurrentIndexType = m_IndexMgrMmFilters.GetCurrentIndexType();
  823. dwCurrentSortOption = m_IndexMgrMmFilters.GetCurrentSortOption();
  824. m_IndexMgrMmFilters.Reset();
  825. for (i = 0; i < m_arrayMmFilters.GetSize(); i++)
  826. {
  827. m_IndexMgrMmFilters.AddItem(m_arrayMmFilters.GetAt(i));
  828. }
  829. m_IndexMgrMmFilters.SortMmFilters(dwCurrentIndexType, dwCurrentSortOption);
  830. //Now work on the specific filters
  831. //remember the original IndexType and Sort options
  832. dwCurrentIndexType = m_IndexMgrMmSpecificFilters.GetCurrentIndexType();
  833. dwCurrentSortOption = m_IndexMgrMmSpecificFilters.GetCurrentSortOption();
  834. m_IndexMgrMmSpecificFilters.Reset();
  835. for (i = 0; i < m_arrayMmSpecificFilters.GetSize(); i++)
  836. {
  837. m_IndexMgrMmSpecificFilters.AddItem(m_arrayMmSpecificFilters.GetAt(i));
  838. }
  839. m_IndexMgrMmSpecificFilters.SortMmFilters(dwCurrentIndexType, dwCurrentSortOption);
  840. Error:
  841. return hr;
  842. }
  843. //Call the SPD to enum filters and put it to our array
  844. HRESULT CSpdInfo::InternalEnumTransportFilters(
  845. DWORD dwLevel,
  846. GUID guid,
  847. CFilterInfoArray * pArray,
  848. DWORD dwPreferredNum /* = 0 by default get all entries*/)
  849. {
  850. Assert(pArray);
  851. HRESULT hr = hrOK;
  852. PTRANSPORT_FILTER pFilters = NULL;
  853. DWORD dwNumFilters = 0;
  854. DWORD dwTemp = 0;
  855. DWORD dwResumeHandle = 0;
  856. FreeItemsAndEmptyArray(*pArray);
  857. do
  858. {
  859. dwTemp = 0;
  860. CWRg(::EnumTransportFilters(
  861. (LPTSTR)(LPCTSTR)m_stMachineName,
  862. dwLevel,
  863. guid,
  864. &pFilters,
  865. dwPreferredNum,
  866. &dwTemp,
  867. &dwResumeHandle
  868. ));
  869. pArray->SetSize(dwNumFilters + dwTemp);
  870. for (int i = 0; i < (int)dwTemp; i++)
  871. {
  872. CFilterInfo * pFltr = new CFilterInfo;
  873. if (NULL == pFltr)
  874. {
  875. hr = E_OUTOFMEMORY;
  876. break;
  877. }
  878. *pFltr = *(pFilters + i);
  879. LoadMiscFilterInfo(pFltr);
  880. (*pArray)[dwNumFilters + i] = pFltr;
  881. }
  882. dwNumFilters += dwTemp;
  883. if (pFilters)
  884. {
  885. SPDApiBufferFree(pFilters);
  886. }
  887. }while (TRUE);
  888. // it will automatically break out from the loop when SPD returns ERROR_NO_DATA
  889. Error:
  890. //this particular error is because we don't have any data. Ignore it
  891. if (HRESULT_FROM_WIN32(ERROR_NO_DATA) == hr)
  892. hr = hrOK;
  893. return hr;
  894. }
  895. HRESULT CSpdInfo::EnumQmFilters()
  896. {
  897. HRESULT hr = S_OK;
  898. int i;
  899. DWORD dwCurrentIndexType = 0;
  900. DWORD dwCurrentSortOption = 0;
  901. CFilterInfoArray arrayTransportFilters;
  902. CFilterInfoArray arrayTunnelFilters;
  903. CFilterInfoArray arraySpTransportFilters;
  904. CFilterInfoArray arraySpTunnelFilters;
  905. CSingleLock cLock(&m_csData);
  906. GUID guid;
  907. ZeroMemory(&guid, sizeof(guid));
  908. CORg(InternalEnumTransportFilters(
  909. ENUM_GENERIC_FILTERS,
  910. guid,
  911. &arrayTransportFilters
  912. ));
  913. CORg(InternalEnumTunnelFilters(
  914. ENUM_GENERIC_FILTERS,
  915. guid,
  916. &arrayTunnelFilters
  917. ));
  918. //We are done with the generic filters.
  919. //Load the specific filters
  920. CORg(InternalEnumTransportFilters(
  921. ENUM_SPECIFIC_FILTERS,
  922. guid,
  923. &arraySpTransportFilters
  924. ));
  925. CORg(InternalEnumTunnelFilters(
  926. ENUM_SPECIFIC_FILTERS,
  927. guid,
  928. &arraySpTunnelFilters
  929. ));
  930. //Update the internal data now
  931. cLock.Lock();
  932. FreeItemsAndEmptyArray(m_arrayFilters);
  933. m_arrayFilters.Copy(arrayTransportFilters);
  934. m_arrayFilters.Append(arrayTunnelFilters);
  935. //remember the original IndexType and Sort options
  936. dwCurrentIndexType = m_IndexMgrFilters.GetCurrentIndexType();
  937. dwCurrentSortOption = m_IndexMgrFilters.GetCurrentSortOption();
  938. m_IndexMgrFilters.Reset();
  939. for (i = 0; i < (int)m_arrayFilters.GetSize(); i++)
  940. {
  941. m_IndexMgrFilters.AddItem(m_arrayFilters.GetAt(i));
  942. }
  943. m_IndexMgrFilters.SortFilters(dwCurrentIndexType, dwCurrentSortOption);
  944. FreeItemsAndEmptyArray(m_arraySpecificFilters);
  945. m_arraySpecificFilters.Copy(arraySpTransportFilters);
  946. m_arraySpecificFilters.Append(arraySpTunnelFilters);
  947. //remember the original IndexType and Sort options
  948. dwCurrentIndexType = m_IndexMgrSpecificFilters.GetCurrentIndexType();
  949. dwCurrentSortOption = m_IndexMgrSpecificFilters.GetCurrentSortOption();
  950. m_IndexMgrSpecificFilters.Reset();
  951. for (i = 0; i < (int)m_arraySpecificFilters.GetSize(); i++)
  952. {
  953. m_IndexMgrSpecificFilters.AddItem(m_arraySpecificFilters.GetAt(i));
  954. }
  955. m_IndexMgrSpecificFilters.SortFilters(dwCurrentIndexType, dwCurrentSortOption);
  956. cLock.Unlock();
  957. Error:
  958. //this particular error is because we don't have any MM policies. Ignore it
  959. if (HRESULT_FROM_WIN32(ERROR_NO_DATA) == hr)
  960. hr = hrOK;
  961. return hr;
  962. }
  963. //Call the SPD to enum filters and put it to our array
  964. HRESULT CSpdInfo::InternalEnumTunnelFilters(
  965. DWORD dwLevel,
  966. GUID guid,
  967. CFilterInfoArray * pArray,
  968. DWORD dwPreferredNum /* = 0 by default get all entries*/)
  969. {
  970. Assert(pArray);
  971. HRESULT hr = hrOK;
  972. FreeItemsAndEmptyArray(*pArray);
  973. PTUNNEL_FILTER pFilters = NULL;
  974. DWORD dwNumFilters = 0;
  975. DWORD dwTemp = 0;
  976. DWORD dwResumeHandle = 0;
  977. do
  978. {
  979. dwTemp = 0;
  980. CWRg(::EnumTunnelFilters(
  981. (LPTSTR)(LPCTSTR)m_stMachineName,
  982. dwLevel,
  983. guid,
  984. &pFilters,
  985. dwPreferredNum,
  986. &dwTemp,
  987. &dwResumeHandle
  988. ));
  989. pArray->SetSize(dwNumFilters + dwTemp);
  990. for (int i = 0; i < (int)dwTemp; i++)
  991. {
  992. CFilterInfo * pFltr = new CFilterInfo;
  993. if (NULL == pFltr)
  994. {
  995. hr = E_OUTOFMEMORY;
  996. break;
  997. }
  998. *pFltr = *(pFilters + i);
  999. LoadMiscFilterInfo(pFltr);
  1000. (*pArray)[dwNumFilters + i] = pFltr;
  1001. }
  1002. dwNumFilters += dwTemp;
  1003. if (pFilters)
  1004. {
  1005. SPDApiBufferFree(pFilters);
  1006. }
  1007. }while (TRUE);
  1008. // it will automatically break out from the loop when SPD returns ERROR_NO_DATA
  1009. Error:
  1010. //this particular error is because we don't have any data. Ignore it
  1011. if (HRESULT_FROM_WIN32(ERROR_NO_DATA) == hr)
  1012. hr = hrOK;
  1013. return hr;
  1014. }
  1015. HRESULT CSpdInfo::EnumSpecificFilters
  1016. (
  1017. GUID * pFilterGuid,
  1018. CFilterInfoArray * parraySpecificFilters,
  1019. FILTER_TYPE fltrType
  1020. )
  1021. {
  1022. Assert (pFilterGuid);
  1023. Assert (parraySpecificFilters);
  1024. HRESULT hr = hrOK;
  1025. int i;
  1026. if (FILTER_TYPE_TUNNEL == fltrType)
  1027. {
  1028. CORg(InternalEnumTunnelFilters(
  1029. ENUM_SELECT_SPECIFIC_FILTERS,
  1030. *pFilterGuid,
  1031. parraySpecificFilters
  1032. ));
  1033. }
  1034. else if (FILTER_TYPE_TRANSPORT == fltrType)
  1035. {
  1036. CORg(InternalEnumTransportFilters(
  1037. ENUM_SELECT_SPECIFIC_FILTERS,
  1038. *pFilterGuid,
  1039. parraySpecificFilters
  1040. ));
  1041. }
  1042. Error:
  1043. //this particular error is because we don't have any MM policies. Ignore it
  1044. if (HRESULT_FROM_WIN32(ERROR_NO_DATA) == hr)
  1045. hr = hrOK;
  1046. return hr;
  1047. }
  1048. //Convert internal filter data to external spd data structure
  1049. //NOTE: the routine only convert severl parameters that are
  1050. //needed for searching match filters
  1051. void CSpdInfo::ConvertToExternalFilterData
  1052. (
  1053. CFilterInfo * pfltrIn,
  1054. TRANSPORT_FILTER * pfltrOut
  1055. )
  1056. {
  1057. ZeroMemory (pfltrOut, sizeof(*pfltrOut));
  1058. //pfltrOut->bCreateMirror = pfltrIn->m_bCreateMirror;
  1059. pfltrOut->DesAddr = pfltrIn->m_DesAddr;
  1060. pfltrOut->DesPort = pfltrIn->m_DesPort;
  1061. pfltrOut->dwDirection = pfltrIn->m_dwDirection;
  1062. //pfltrOut->dwWeight = pfltrIn->m_dwWeight;
  1063. //pfltrOut->FilterFlag = pfltrIn->;
  1064. //pfltrOut->gFilterID = pfltrIn->m_guidFltr;
  1065. //pfltrOut->gPolicyID = pfltrIn->m_guidPolicyID;
  1066. //pfltrOut->InterfaceType = pfltrIn->m_InterfaceType;
  1067. pfltrOut->Protocol = pfltrIn->m_Protocol;
  1068. pfltrOut->SrcAddr = pfltrIn->m_SrcAddr;
  1069. pfltrOut->SrcPort = pfltrIn->m_SrcPort;
  1070. }
  1071. HRESULT CSpdInfo::GetMatchFilters
  1072. (
  1073. CFilterInfo * pfltrSearchCondition,
  1074. DWORD dwPreferredNum,
  1075. CFilterInfoArray * parrFilters
  1076. )
  1077. {
  1078. HRESULT hr = S_OK;
  1079. Assert (pfltrSearchCondition);
  1080. Assert (parrFilters);
  1081. PTRANSPORT_FILTER pMatchedFilters = NULL;
  1082. PIPSEC_QM_POLICY pMatchedPolicies = NULL;
  1083. DWORD dwNumMatches = 0;
  1084. DWORD dwResumeHandle = 0;
  1085. DWORD i = 0;
  1086. TRANSPORT_FILTER SpdFltr;
  1087. ConvertToExternalFilterData(pfltrSearchCondition, &SpdFltr);
  1088. CWRg(::MatchTransportFilter (
  1089. (LPTSTR)((LPCTSTR)m_stMachineName),
  1090. &SpdFltr,
  1091. 0, //Don't return default policy if no match
  1092. &pMatchedFilters,
  1093. &pMatchedPolicies,
  1094. dwPreferredNum, //enum all //BUGBUG should be 0 instead of 1000
  1095. &dwNumMatches,
  1096. &dwResumeHandle
  1097. ));
  1098. //Todo check whether we really got all.
  1099. parrFilters->SetSize(dwNumMatches);
  1100. for (i = 0; i < dwNumMatches; i++)
  1101. {
  1102. CFilterInfo * pFltr = new CFilterInfo;
  1103. *pFltr = *(pMatchedFilters + i);
  1104. LoadMiscFilterInfo(pFltr);
  1105. (*parrFilters)[i] = pFltr;
  1106. }
  1107. if (pMatchedFilters)
  1108. SPDApiBufferFree(pMatchedFilters);
  1109. if (pMatchedPolicies)
  1110. SPDApiBufferFree(pMatchedPolicies);
  1111. Error:
  1112. //this particular error is because we don't have any data. Ignore it
  1113. if (HRESULT_FROM_WIN32(ERROR_NO_DATA) == hr)
  1114. hr = hrOK;
  1115. return hr;
  1116. }
  1117. //Convert internal filter data to external spd data structure
  1118. //NOTE: the routine only convert severl parameters that are
  1119. //needed for searching match filters
  1120. void CSpdInfo::ConvertToExternalMMFilterData
  1121. (
  1122. CMmFilterInfo * pfltrIn,
  1123. MM_FILTER * pfltrOut
  1124. )
  1125. {
  1126. ZeroMemory (pfltrOut, sizeof(*pfltrOut));
  1127. //pfltrOut->bCreateMirror = pfltrIn->m_bCreateMirror;
  1128. pfltrOut->DesAddr = pfltrIn->m_DesAddr;
  1129. pfltrOut->dwDirection = pfltrIn->m_dwDirection;
  1130. //pfltrOut->dwWeight = pfltrIn->m_dwWeight;
  1131. //pfltrOut->gFilterID = pfltrIn->m_guidFltr;
  1132. //pfltrOut->gPolicyID = pfltrIn->m_guidPolicyID;
  1133. //pfltrOut->InterfaceType = pfltrIn->m_InterfaceType;
  1134. pfltrOut->SrcAddr = pfltrIn->m_SrcAddr;
  1135. }
  1136. HRESULT CSpdInfo::GetMatchMMFilters
  1137. (
  1138. CMmFilterInfo * pfltrSearchCondition,
  1139. DWORD dwPreferredNum,
  1140. CMmFilterInfoArray * parrFilters
  1141. )
  1142. {
  1143. HRESULT hr = S_OK;
  1144. Assert (pfltrSearchCondition);
  1145. Assert (parrFilters);
  1146. PMM_FILTER pMatchedFilters = NULL;
  1147. PIPSEC_MM_POLICY pMatchedPolicies = NULL;
  1148. PMM_AUTH_METHODS pMatchedAuths = NULL;
  1149. DWORD dwNumMatches = 0;
  1150. DWORD dwResumeHandle = 0;
  1151. DWORD i = 0;
  1152. MM_FILTER SpdFltr;
  1153. ConvertToExternalMMFilterData(pfltrSearchCondition, &SpdFltr);
  1154. CWRg(::MatchMMFilter (
  1155. (LPTSTR)((LPCTSTR)m_stMachineName),
  1156. &SpdFltr,
  1157. 0, //Don't return default policy if no match
  1158. &pMatchedFilters,
  1159. &pMatchedPolicies,
  1160. &pMatchedAuths,
  1161. dwPreferredNum, //enum all //TODO BUGBUG should be 0 instead of 1000
  1162. &dwNumMatches,
  1163. &dwResumeHandle
  1164. ));
  1165. //Todo check whether we really got all.
  1166. parrFilters->SetSize(dwNumMatches);
  1167. for (i = 0; i < dwNumMatches; i++)
  1168. {
  1169. CMmFilterInfo * pFltr = new CMmFilterInfo;
  1170. *pFltr = *(pMatchedFilters + i);
  1171. LoadMiscMmFilterInfo(pFltr);
  1172. (*parrFilters)[i] = pFltr;
  1173. }
  1174. if (pMatchedFilters)
  1175. SPDApiBufferFree(pMatchedFilters);
  1176. if (pMatchedPolicies)
  1177. SPDApiBufferFree(pMatchedPolicies);
  1178. if (pMatchedAuths)
  1179. SPDApiBufferFree(pMatchedAuths);
  1180. Error:
  1181. //this particular error is because we don't have any data. Ignore it
  1182. if (HRESULT_FROM_WIN32(ERROR_NO_DATA) == hr)
  1183. hr = hrOK;
  1184. return hr;
  1185. }
  1186. HRESULT CSpdInfo::EnumMmSpecificFilters
  1187. (
  1188. GUID * pGenFilterGuid,
  1189. CMmFilterInfoArray * parraySpecificFilters
  1190. )
  1191. {
  1192. Assert (pGenFilterGuid);
  1193. Assert (parraySpecificFilters);
  1194. HRESULT hr = hrOK;
  1195. DWORD dwNumFilters = 0;
  1196. DWORD dwResumeHandle = 0;
  1197. int i;
  1198. parraySpecificFilters->RemoveAll();
  1199. CORg(InternalEnumMmFilters(
  1200. ENUM_SELECT_SPECIFIC_FILTERS,
  1201. *pGenFilterGuid,
  1202. parraySpecificFilters
  1203. ));
  1204. Error:
  1205. //this particular error is because we don't have any MM policies. Ignore it
  1206. if (HRESULT_FROM_WIN32(ERROR_NO_DATA) == hr)
  1207. hr = hrOK;
  1208. return hr;
  1209. }
  1210. //Call the SPD to enum policies and put it to our array
  1211. HRESULT CSpdInfo::InternalEnumMmPolicies(
  1212. CMmPolicyInfoArray * pArray,
  1213. DWORD dwPreferredNum /* = 0 by default get all entries*/)
  1214. {
  1215. Assert(pArray);
  1216. HRESULT hr = hrOK;
  1217. PIPSEC_MM_POLICY pPolicies = NULL;
  1218. DWORD dwNumPolicies = 0;
  1219. DWORD dwTemp = 0;
  1220. DWORD dwResumeHandle = 0;
  1221. FreeItemsAndEmptyArray(*pArray);
  1222. do
  1223. {
  1224. dwTemp = 0;
  1225. CWRg(::EnumMMPolicies(
  1226. (LPTSTR)(LPCTSTR)m_stMachineName,
  1227. &pPolicies,
  1228. dwPreferredNum,
  1229. &dwTemp,
  1230. &dwResumeHandle
  1231. ));
  1232. pArray->SetSize(dwNumPolicies + dwTemp);
  1233. for (int i = 0; i < (int)dwTemp; i++)
  1234. {
  1235. CMmPolicyInfo * pPol = new CMmPolicyInfo;
  1236. if (NULL == pPol)
  1237. {
  1238. hr = E_OUTOFMEMORY;
  1239. break;
  1240. }
  1241. *pPol = *(pPolicies + i);
  1242. (*pArray)[dwNumPolicies + i] = pPol;
  1243. }
  1244. dwNumPolicies += dwTemp;
  1245. if (pPolicies)
  1246. {
  1247. SPDApiBufferFree(pPolicies);
  1248. }
  1249. }while (TRUE);
  1250. // it will automatically break out from the loop when SPD returns ERROR_NO_DATA
  1251. Error:
  1252. //this particular error is because we don't have any data. Ignore it
  1253. if (HRESULT_FROM_WIN32(ERROR_NO_DATA) == hr)
  1254. hr = hrOK;
  1255. return hr;
  1256. }
  1257. HRESULT CSpdInfo::EnumMmPolicies()
  1258. {
  1259. HRESULT hr = hrOK;
  1260. CSingleLock cLock(&m_csData);
  1261. DWORD dwCurrentIndexType;
  1262. DWORD dwCurrentSortOption;
  1263. int i;
  1264. CMmPolicyInfoArray arrayTemp;
  1265. CORg(InternalEnumMmPolicies(
  1266. &arrayTemp,
  1267. 0 //enum all policies
  1268. ));
  1269. cLock.Lock();
  1270. FreeItemsAndEmptyArray(m_arrayMmPolicies);
  1271. m_arrayMmPolicies.Copy(arrayTemp);
  1272. //remember the original IndexType and Sort options
  1273. dwCurrentIndexType = m_IndexMgrMmPolicies.GetCurrentIndexType();
  1274. dwCurrentSortOption = m_IndexMgrMmPolicies.GetCurrentSortOption();
  1275. m_IndexMgrMmPolicies.Reset();
  1276. for (i = 0; i < (int)m_arrayMmPolicies.GetSize(); i++)
  1277. {
  1278. m_IndexMgrMmPolicies.AddItem(m_arrayMmPolicies.GetAt(i));
  1279. }
  1280. m_IndexMgrMmPolicies.Sort(dwCurrentIndexType, dwCurrentSortOption);
  1281. Error:
  1282. //this particular error is because we don't have any MM policies. Ignore it
  1283. if (HRESULT_FROM_WIN32(ERROR_NO_DATA) == hr)
  1284. hr = hrOK;
  1285. return hr;
  1286. }
  1287. //Call the SPD to enum policies and put it to our array
  1288. HRESULT CSpdInfo::InternalEnumQmPolicies(
  1289. CQmPolicyInfoArray * pArray,
  1290. DWORD dwPreferredNum /* = 0 by default get all entries*/)
  1291. {
  1292. Assert(pArray);
  1293. HRESULT hr = hrOK;
  1294. PIPSEC_QM_POLICY pPolicies = NULL;
  1295. DWORD dwNumPolicies = 0;
  1296. DWORD dwTemp = 0;
  1297. DWORD dwResumeHandle = 0;
  1298. FreeItemsAndEmptyArray(*pArray);
  1299. do
  1300. {
  1301. dwTemp = 0;
  1302. CWRg(::EnumQMPolicies(
  1303. (LPTSTR)(LPCTSTR)m_stMachineName,
  1304. &pPolicies,
  1305. dwPreferredNum,
  1306. &dwTemp,
  1307. &dwResumeHandle
  1308. ));
  1309. pArray->SetSize(dwNumPolicies + dwTemp);
  1310. for (int i = 0; i < (int)dwTemp; i++)
  1311. {
  1312. CQmPolicyInfo * pPol = new CQmPolicyInfo;
  1313. if (NULL == pPol)
  1314. {
  1315. hr = E_OUTOFMEMORY;
  1316. break;
  1317. }
  1318. *pPol = *(pPolicies + i);
  1319. (*pArray)[dwNumPolicies + i] = pPol;
  1320. }
  1321. dwNumPolicies += dwTemp;
  1322. if (pPolicies)
  1323. {
  1324. SPDApiBufferFree(pPolicies);
  1325. }
  1326. }while (TRUE);
  1327. // it will automatically break out from the loop when SPD returns ERROR_NO_DATA
  1328. Error:
  1329. //this particular error is because we don't have any data. Ignore it
  1330. if (HRESULT_FROM_WIN32(ERROR_NO_DATA) == hr)
  1331. hr = hrOK;
  1332. return hr;
  1333. }
  1334. HRESULT CSpdInfo::EnumQmPolicies()
  1335. {
  1336. HRESULT hr = hrOK;
  1337. CSingleLock cLock(&m_csData);
  1338. DWORD dwCurrentIndexType;
  1339. DWORD dwCurrentSortOption;
  1340. int i;
  1341. CQmPolicyInfoArray arrayTemp;
  1342. CORg(InternalEnumQmPolicies(
  1343. &arrayTemp
  1344. ));
  1345. cLock.Lock();
  1346. FreeItemsAndEmptyArray(m_arrayQmPolicies);
  1347. m_arrayQmPolicies.Copy(arrayTemp);
  1348. //remember the original IndexType and Sort options
  1349. dwCurrentIndexType = m_IndexMgrQmPolicies.GetCurrentIndexType();
  1350. dwCurrentSortOption = m_IndexMgrQmPolicies.GetCurrentSortOption();
  1351. m_IndexMgrQmPolicies.Reset();
  1352. for (i = 0; i < (int)m_arrayQmPolicies.GetSize(); i++)
  1353. {
  1354. m_IndexMgrQmPolicies.AddItem(m_arrayQmPolicies.GetAt(i));
  1355. }
  1356. m_IndexMgrQmPolicies.Sort(dwCurrentIndexType, dwCurrentSortOption);
  1357. Error:
  1358. //this particular error is because we don't have any QM policies. Ignore it
  1359. if (HRESULT_FROM_WIN32(ERROR_NO_DATA) == hr)
  1360. hr = hrOK;
  1361. return hr;
  1362. }
  1363. DWORD CSpdInfo::GetMmAuthMethodsCount()
  1364. {
  1365. CSingleLock cLock(&m_csData);
  1366. cLock.Lock();
  1367. return (DWORD)m_arrMmAuthMethods.GetSize();
  1368. }
  1369. DWORD CSpdInfo::GetMmSACount()
  1370. {
  1371. CSingleLock cLock(&m_csData);
  1372. cLock.Lock();
  1373. return (DWORD)m_arrayMmSAs.GetSize();
  1374. }
  1375. DWORD CSpdInfo::GetMmPolicyCount()
  1376. {
  1377. CSingleLock cLock(&m_csData);
  1378. cLock.Lock();
  1379. return (DWORD)m_arrayMmPolicies.GetSize();
  1380. }
  1381. DWORD CSpdInfo::GetQmSACount()
  1382. {
  1383. CSingleLock cLock(&m_csData);
  1384. cLock.Lock();
  1385. return (DWORD)m_arrayQmSAs.GetSize();
  1386. }
  1387. DWORD CSpdInfo::GetQmPolicyCount()
  1388. {
  1389. CSingleLock cLock(&m_csData);
  1390. cLock.Lock();
  1391. return (DWORD)m_arrayQmPolicies.GetSize();
  1392. }
  1393. DWORD CSpdInfo::GetQmFilterCountOfCurrentViewType()
  1394. {
  1395. CSingleLock cLock(&m_csData);
  1396. cLock.Lock();
  1397. return (DWORD)(m_IndexMgrFilters.GetItemCount());
  1398. }
  1399. DWORD CSpdInfo::GetQmSpFilterCountOfCurrentViewType()
  1400. {
  1401. CSingleLock cLock(&m_csData);
  1402. cLock.Lock();
  1403. return (DWORD)(m_IndexMgrSpecificFilters.GetItemCount());
  1404. }
  1405. DWORD CSpdInfo::GetMmFilterCount()
  1406. {
  1407. CSingleLock cLock(&m_csData);
  1408. cLock.Lock();
  1409. return (DWORD)(m_arrayMmFilters.GetSize());
  1410. }
  1411. DWORD CSpdInfo::GetMmSpecificFilterCount()
  1412. {
  1413. CSingleLock cLock(&m_csData);
  1414. cLock.Lock();
  1415. return (DWORD)(m_arrayMmSpecificFilters.GetSize());
  1416. }
  1417. HRESULT CSpdInfo::GetFilterInfo(int iIndex, CFilterInfo * pFilter)
  1418. {
  1419. HRESULT hr = S_OK;
  1420. Assert(pFilter);
  1421. if (NULL == pFilter)
  1422. return E_INVALIDARG;
  1423. CSingleLock cLock(&m_csData);
  1424. cLock.Lock();
  1425. if (iIndex < m_arrayFilters.GetSize())
  1426. {
  1427. CFilterInfo * pFltrData = (CFilterInfo*)m_IndexMgrFilters.GetItemData(iIndex);
  1428. Assert(pFltrData);
  1429. *pFilter = *pFltrData;
  1430. }
  1431. else
  1432. {
  1433. hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
  1434. }
  1435. return hr;
  1436. }
  1437. HRESULT CSpdInfo::GetSpecificFilterInfo(int iIndex, CFilterInfo * pFilter)
  1438. {
  1439. HRESULT hr = S_OK;
  1440. Assert(pFilter);
  1441. if (NULL == pFilter)
  1442. return E_INVALIDARG;
  1443. CSingleLock cLock(&m_csData);
  1444. cLock.Lock();
  1445. if (iIndex < m_arraySpecificFilters.GetSize())
  1446. {
  1447. CFilterInfo * pFltrData = (CFilterInfo*)m_IndexMgrSpecificFilters.GetItemData(iIndex);
  1448. Assert(pFltrData);
  1449. *pFilter = *pFltrData;
  1450. }
  1451. else
  1452. {
  1453. hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
  1454. }
  1455. return hr;
  1456. }
  1457. HRESULT CSpdInfo::GetMmFilterInfo(int iIndex, CMmFilterInfo * pFltr)
  1458. {
  1459. HRESULT hr = S_OK;
  1460. Assert(pFltr);
  1461. if (NULL == pFltr)
  1462. return E_INVALIDARG;
  1463. CSingleLock cLock(&m_csData);
  1464. cLock.Lock();
  1465. if (iIndex < m_arrayMmFilters.GetSize())
  1466. {
  1467. CMmFilterInfo * pFltrData = (CMmFilterInfo*)m_IndexMgrMmFilters.GetItemData(iIndex);
  1468. Assert(pFltrData);
  1469. *pFltr = *pFltrData;
  1470. }
  1471. else
  1472. {
  1473. hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
  1474. }
  1475. return hr;
  1476. }
  1477. HRESULT CSpdInfo::GetMmSpecificFilterInfo
  1478. (
  1479. int iIndex,
  1480. CMmFilterInfo * pFltr
  1481. )
  1482. {
  1483. HRESULT hr = S_OK;
  1484. Assert(pFltr);
  1485. if (NULL == pFltr)
  1486. return E_INVALIDARG;
  1487. CSingleLock cLock(&m_csData);
  1488. cLock.Lock();
  1489. if (iIndex < m_arrayMmSpecificFilters.GetSize())
  1490. {
  1491. CMmFilterInfo * pFltrData = (CMmFilterInfo*)m_IndexMgrMmSpecificFilters.GetItemData(iIndex);
  1492. Assert(pFltrData);
  1493. *pFltr = *pFltrData;
  1494. }
  1495. else
  1496. {
  1497. hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
  1498. }
  1499. return hr;
  1500. }
  1501. HRESULT CSpdInfo::GetMmPolicyInfo(int iIndex, CMmPolicyInfo * pMmPolicy)
  1502. {
  1503. HRESULT hr = hrOK;
  1504. Assert(pMmPolicy);
  1505. if (NULL == pMmPolicy)
  1506. return E_INVALIDARG;
  1507. CSingleLock cLock(&m_csData);
  1508. cLock.Lock();
  1509. if (iIndex < m_arrayMmPolicies.GetSize())
  1510. {
  1511. CMmPolicyInfo * pPolicy = (CMmPolicyInfo*) m_IndexMgrMmPolicies.GetItemData(iIndex);
  1512. *pMmPolicy = *pPolicy;
  1513. }
  1514. else
  1515. {
  1516. hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
  1517. }
  1518. return hr;
  1519. }
  1520. HRESULT CSpdInfo::GetMmAuthMethodsInfo(int iIndex, CMmAuthMethods * pMmAuth)
  1521. {
  1522. HRESULT hr = hrOK;
  1523. CSingleLock cLock(&m_csData);
  1524. cLock.Lock();
  1525. if (iIndex < m_arrMmAuthMethods.GetSize())
  1526. {
  1527. *pMmAuth = *m_arrMmAuthMethods[iIndex];
  1528. }
  1529. else
  1530. {
  1531. hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
  1532. }
  1533. return hr;
  1534. }
  1535. HRESULT CSpdInfo::GetMmSAInfo(int iIndex, CMmSA * pSA)
  1536. {
  1537. HRESULT hr = hrOK;
  1538. CSingleLock cLock(&m_csData);
  1539. cLock.Lock();
  1540. Assert(pSA);
  1541. if (NULL == pSA)
  1542. return E_INVALIDARG;
  1543. if (iIndex < m_arrayMmSAs.GetSize())
  1544. {
  1545. CMmSA * pSATemp = (CMmSA*) m_IndexMgrMmSAs.GetItemData(iIndex);
  1546. *pSA = *pSATemp;
  1547. }
  1548. else
  1549. {
  1550. hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
  1551. }
  1552. return hr;
  1553. }
  1554. HRESULT CSpdInfo::GetQmSAInfo(int iIndex, CQmSA * pSA)
  1555. {
  1556. HRESULT hr = hrOK;
  1557. CSingleLock cLock(&m_csData);
  1558. cLock.Lock();
  1559. Assert(pSA);
  1560. if (NULL == pSA)
  1561. return E_INVALIDARG;
  1562. if (iIndex < m_arrayQmSAs.GetSize())
  1563. {
  1564. CQmSA * pSATemp = (CQmSA*) m_IndexMgrQmSAs.GetItemData(iIndex);
  1565. *pSA = *pSATemp;
  1566. }
  1567. else
  1568. {
  1569. hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
  1570. }
  1571. return hr;
  1572. }
  1573. HRESULT CSpdInfo::GetQmPolicyInfo(int iIndex, CQmPolicyInfo * pQmPolicy)
  1574. {
  1575. HRESULT hr = hrOK;
  1576. if (NULL == pQmPolicy)
  1577. return E_INVALIDARG;
  1578. CSingleLock cLock(&m_csData);
  1579. cLock.Lock();
  1580. if (iIndex < m_arrayQmPolicies.GetSize())
  1581. {
  1582. CQmPolicyInfo * pPolicy = (CQmPolicyInfo*) m_IndexMgrQmPolicies.GetItemData(iIndex);
  1583. *pQmPolicy = *pPolicy;
  1584. }
  1585. else
  1586. {
  1587. hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
  1588. }
  1589. return hr;
  1590. }
  1591. HRESULT CSpdInfo::GetQmPolicyNameByGuid(GUID guid, CString * pst)
  1592. {
  1593. HRESULT hr = hrOK;
  1594. if (NULL == pst)
  1595. return E_INVALIDARG;
  1596. pst->Empty();
  1597. PIPSEC_QM_POLICY pPolicy = NULL;
  1598. CWRg(::GetQMPolicyByID(
  1599. (LPTSTR)(LPCTSTR) m_stMachineName,
  1600. guid,
  1601. &pPolicy));
  1602. if (pPolicy)
  1603. {
  1604. *pst = pPolicy->pszPolicyName;
  1605. SPDApiBufferFree(pPolicy);
  1606. }
  1607. else
  1608. {
  1609. hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
  1610. }
  1611. Error:
  1612. return hr;
  1613. }
  1614. HRESULT CSpdInfo::GetMmPolicyNameByGuid(GUID guid, CString * pst)
  1615. {
  1616. HRESULT hr = hrOK;
  1617. if (NULL == pst)
  1618. return E_INVALIDARG;
  1619. pst->Empty();
  1620. PIPSEC_MM_POLICY pPolicy = NULL;
  1621. CWRg(::GetMMPolicyByID(
  1622. (LPTSTR)(LPCTSTR) m_stMachineName,
  1623. guid,
  1624. &pPolicy));
  1625. if (pPolicy)
  1626. {
  1627. *pst = pPolicy->pszPolicyName;
  1628. SPDApiBufferFree(pPolicy);
  1629. }
  1630. else
  1631. {
  1632. hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
  1633. }
  1634. Error:
  1635. return hr;
  1636. }
  1637. HRESULT CSpdInfo::GetMmAuthMethodsInfoByGuid(GUID guid, CMmAuthMethods * pMmAuth)
  1638. {
  1639. HRESULT hr = hrOK;
  1640. PMM_AUTH_METHODS pSpdAuth = NULL;
  1641. CWRg(::GetMMAuthMethods(
  1642. (LPTSTR)(LPCTSTR) m_stMachineName,
  1643. guid,
  1644. &pSpdAuth));
  1645. if (pSpdAuth)
  1646. {
  1647. *pMmAuth = *pSpdAuth;
  1648. SPDApiBufferFree(pSpdAuth);
  1649. }
  1650. else
  1651. {
  1652. hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
  1653. }
  1654. Error:
  1655. return hr;
  1656. }
  1657. HRESULT CSpdInfo::SortFilters(DWORD dwIndexType, DWORD dwSortOptions)
  1658. {
  1659. return m_IndexMgrFilters.SortFilters(dwIndexType, dwSortOptions);
  1660. }
  1661. HRESULT CSpdInfo::SortSpecificFilters(DWORD dwIndexType, DWORD dwSortOptions)
  1662. {
  1663. return m_IndexMgrSpecificFilters.SortFilters(dwIndexType, dwSortOptions);
  1664. }
  1665. HRESULT CSpdInfo::SortMmFilters(DWORD dwIndexType, DWORD dwSortOptions)
  1666. {
  1667. return m_IndexMgrMmFilters.SortMmFilters(dwIndexType, dwSortOptions);
  1668. }
  1669. HRESULT CSpdInfo::SortMmSpecificFilters(DWORD dwIndexType, DWORD dwSortOptions)
  1670. {
  1671. return m_IndexMgrMmSpecificFilters.SortMmFilters(dwIndexType, dwSortOptions);
  1672. }
  1673. HRESULT CSpdInfo::SortMmPolicies(DWORD dwIndexType, DWORD dwSortOptions)
  1674. {
  1675. return m_IndexMgrMmPolicies.Sort(dwIndexType, dwSortOptions);
  1676. }
  1677. HRESULT CSpdInfo::SortQmPolicies(DWORD dwIndexType, DWORD dwSortOptions)
  1678. {
  1679. return m_IndexMgrQmPolicies.Sort(dwIndexType, dwSortOptions);
  1680. }
  1681. HRESULT CSpdInfo::SortMmSAs(DWORD dwIndexType, DWORD dwSortOptions)
  1682. {
  1683. return m_IndexMgrMmSAs.Sort(dwIndexType, dwSortOptions);
  1684. }
  1685. HRESULT CSpdInfo::SortQmSAs(DWORD dwIndexType, DWORD dwSortOptions)
  1686. {
  1687. return m_IndexMgrQmSAs.Sort(dwIndexType, dwSortOptions);
  1688. }
  1689. HRESULT CSpdInfo::EnumQmSAsFromMmSA(const CMmSA & MmSA, CQmSAArray * parrayQmSAs)
  1690. {
  1691. HRESULT hr = hrOK;
  1692. if (NULL == parrayQmSAs)
  1693. return E_INVALIDARG;
  1694. FreeItemsAndEmptyArray(*parrayQmSAs);
  1695. for (int i = 0; i < m_arrayQmSAs.GetSize(); i++)
  1696. {
  1697. if (0 == memcmp(&MmSA.m_MMSpi, &(m_arrayQmSAs[i]->m_MMSpi), sizeof(MmSA.m_MMSpi)))
  1698. {
  1699. CQmSA * pSA = new CQmSA;
  1700. if (NULL == pSA)
  1701. {
  1702. FreeItemsAndEmptyArray(*parrayQmSAs);
  1703. hr = E_OUTOFMEMORY;
  1704. break;
  1705. }
  1706. *pSA = *(m_arrayQmSAs[i]);
  1707. parrayQmSAs->Add(pSA);
  1708. }
  1709. }
  1710. return hr;
  1711. }
  1712. HRESULT CSpdInfo::LoadStatistics()
  1713. {
  1714. HRESULT hr;
  1715. PIPSEC_STATISTICS pIpsecStats = NULL;
  1716. IKE_STATISTICS ikeStats;
  1717. ZeroMemory(&ikeStats, sizeof(ikeStats));
  1718. CWRg(::IPSecQueryIKEStatistics((LPTSTR)(LPCTSTR)m_stMachineName,
  1719. &ikeStats));
  1720. m_IkeStats = ikeStats;
  1721. CWRg(::QueryIPSecStatistics((LPTSTR)(LPCTSTR)m_stMachineName,
  1722. &pIpsecStats));
  1723. Assert(pIpsecStats);
  1724. m_IpsecStats = *pIpsecStats;
  1725. if (pIpsecStats)
  1726. {
  1727. SPDApiBufferFree(pIpsecStats);
  1728. }
  1729. Error:
  1730. return hr;
  1731. }
  1732. // Get the current cached statistics
  1733. void CSpdInfo::GetLoadedStatistics(CIkeStatistics * pIkeStats, CIpsecStatistics * pIpsecStats)
  1734. {
  1735. if (pIkeStats)
  1736. {
  1737. *pIkeStats = m_IkeStats;
  1738. }
  1739. if (pIpsecStats)
  1740. {
  1741. *pIpsecStats = m_IpsecStats;
  1742. }
  1743. }
  1744. void CSpdInfo::ChangeQmFilterViewType(FILTER_TYPE FltrType)
  1745. {
  1746. CSingleLock cLock(&m_csData);
  1747. cLock.Lock();
  1748. DWORD dwCurrentIndexType = m_IndexMgrFilters.GetCurrentIndexType();
  1749. DWORD dwCurrentSortOption = m_IndexMgrFilters.GetCurrentSortOption();
  1750. m_IndexMgrFilters.Reset();
  1751. for (int i = 0; i < m_arrayFilters.GetSize(); i++)
  1752. {
  1753. if (FILTER_TYPE_ANY == FltrType ||
  1754. FltrType == m_arrayFilters[i]->m_FilterType)
  1755. {
  1756. m_IndexMgrFilters.AddItem(m_arrayFilters.GetAt(i));
  1757. }
  1758. }
  1759. m_IndexMgrFilters.SortFilters(dwCurrentIndexType, dwCurrentSortOption);
  1760. }
  1761. void CSpdInfo::ChangeQmSpFilterViewType(FILTER_TYPE FltrType)
  1762. {
  1763. CSingleLock cLock(&m_csData);
  1764. cLock.Lock();
  1765. DWORD dwCurrentIndexType = m_IndexMgrSpecificFilters.GetCurrentIndexType();
  1766. DWORD dwCurrentSortOption = m_IndexMgrSpecificFilters.GetCurrentSortOption();
  1767. m_IndexMgrSpecificFilters.Reset();
  1768. for (int i = 0; i < m_arraySpecificFilters.GetSize(); i++)
  1769. {
  1770. if (FILTER_TYPE_ANY == FltrType ||
  1771. FltrType == m_arraySpecificFilters[i]->m_FilterType)
  1772. {
  1773. m_IndexMgrSpecificFilters.AddItem(m_arraySpecificFilters.GetAt(i));
  1774. }
  1775. }
  1776. m_IndexMgrSpecificFilters.SortFilters(dwCurrentIndexType, dwCurrentSortOption);
  1777. }
  1778. HRESULT CSpdInfo::LoadMiscMmSAInfo(CMmSA * pSA)
  1779. {
  1780. Assert(pSA);
  1781. return GetMmPolicyNameByGuid(pSA->m_guidPolicy, &pSA->m_stPolicyName);
  1782. }
  1783. HRESULT CSpdInfo::LoadMiscQmSAInfo(CQmSA * pSA)
  1784. {
  1785. Assert(pSA);
  1786. return GetQmPolicyNameByGuid(pSA->m_guidPolicy, &pSA->m_stPolicyName);
  1787. }
  1788. HRESULT CSpdInfo::LoadMiscFilterInfo(CFilterInfo * pFltr)
  1789. {
  1790. Assert(pFltr);
  1791. return GetQmPolicyNameByGuid(pFltr->m_guidPolicyID, &pFltr->m_stPolicyName);
  1792. }
  1793. HRESULT CSpdInfo::LoadMiscMmFilterInfo(CMmFilterInfo * pFltr)
  1794. {
  1795. Assert(pFltr);
  1796. HRESULT hr = S_OK;
  1797. HRESULT hrTemp;
  1798. CMmAuthMethods auth;
  1799. hrTemp = GetMmAuthMethodsInfoByGuid(pFltr->m_guidAuthID, &auth);
  1800. if (FAILED(hrTemp))
  1801. hr = hrTemp;
  1802. pFltr->m_stAuthDescription = auth.m_stDescription;
  1803. hrTemp = GetMmPolicyNameByGuid(pFltr->m_guidPolicyID, &pFltr->m_stPolicyName);
  1804. if (FAILED(hrTemp))
  1805. hr = hrTemp;
  1806. return hr;
  1807. }
  1808. STDMETHODIMP
  1809. CSpdInfo::Destroy()
  1810. {
  1811. //$REVIEW this routine get called when doing auto-refresh
  1812. //We don't need to clean up anything at this time.
  1813. //Each array (Filter, SA, policy...) will get cleaned up when calling the
  1814. //corresponding enum function.
  1815. return S_OK;
  1816. }
  1817. DWORD
  1818. CSpdInfo::GetInitInfo()
  1819. {
  1820. CSingleLock cLock(&m_csData);
  1821. cLock.Lock();
  1822. return m_Init;
  1823. }
  1824. void
  1825. CSpdInfo::SetInitInfo(DWORD dwInitInfo)
  1826. {
  1827. CSingleLock cLock(&m_csData);
  1828. cLock.Lock();
  1829. m_Init=dwInitInfo;
  1830. }
  1831. DWORD
  1832. CSpdInfo::GetActiveInfo()
  1833. {
  1834. CSingleLock cLock(&m_csData);
  1835. cLock.Lock();
  1836. return m_Active;
  1837. }
  1838. void
  1839. CSpdInfo::SetActiveInfo(DWORD dwActiveInfo)
  1840. {
  1841. CSingleLock cLock(&m_csData);
  1842. cLock.Lock();
  1843. m_Active=dwActiveInfo;
  1844. }
  1845. /*!--------------------------------------------------------------------------
  1846. CreateSpdInfo
  1847. Helper to create the SpdInfo object.
  1848. ---------------------------------------------------------------------------*/
  1849. HRESULT
  1850. CreateSpdInfo(ISpdInfo ** ppSpdInfo)
  1851. {
  1852. AFX_MANAGE_STATE(AfxGetModuleState());
  1853. SPISpdInfo spSpdInfo;
  1854. ISpdInfo * pSpdInfo = NULL;
  1855. HRESULT hr = hrOK;
  1856. COM_PROTECT_TRY
  1857. {
  1858. pSpdInfo = new CSpdInfo;
  1859. // Do this so that it will get freed on error
  1860. spSpdInfo = pSpdInfo;
  1861. *ppSpdInfo = spSpdInfo.Transfer();
  1862. }
  1863. COM_PROTECT_CATCH
  1864. return hr;
  1865. }
  1866. //
  1867. // FUNCTIONS: MIDL_user_allocate and MIDL_user_free
  1868. //
  1869. // PURPOSE: Used by stubs to allocate and free memory
  1870. // in standard RPC calls. Not used when
  1871. // [enable_allocate] is specified in the .acf.
  1872. //
  1873. //
  1874. // PARAMETERS:
  1875. // See documentations.
  1876. //
  1877. // RETURN VALUE:
  1878. // Exceptions on error. This is not required,
  1879. // you can use -error allocation on the midl.exe
  1880. // command line instead.
  1881. //
  1882. //
  1883. void * __RPC_USER MIDL_user_allocate(size_t size)
  1884. {
  1885. return(HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, size));
  1886. }
  1887. void __RPC_USER MIDL_user_free( void *pointer)
  1888. {
  1889. HeapFree(GetProcessHeap(), 0, pointer);
  1890. }