windows-nt/Source/XPSP1/NT/net/mmc/ipsecmon/spddb.cpp
2020-09-26 16:20:57 +08:00

2430 lines
53 KiB
C++

/**********************************************************************/
/** Microsoft Windows/NT **/
/** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
/**********************************************************************/
/*
spddb.h
FILE HISTORY:
*/
#include "stdafx.h"
#include "DynamLnk.h"
#include "spddb.h"
#include "spdutil.h"
#include "security.h"
#include "lm.h"
#include "service.h"
#define AVG_PREFERRED_ENUM_COUNT 40
#define DEFAULT_SECURITY_PKG _T("negotiate")
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
// internal functions
BOOL IsUserAdmin(LPCTSTR pszMachine, PSID AccountSid);
BOOL LookupAliasFromRid(LPWSTR TargetComputer, DWORD Rid, LPWSTR Name, PDWORD cchName);
DWORD ValidateDomainAccount(IN CString Machine, IN CString UserName, IN CString Domain, OUT PSID * AccountSid);
NTSTATUS ValidatePassword(IN LPCWSTR UserName, IN LPCWSTR Domain, IN LPCWSTR Password);
DWORD GetCurrentUser(CString & strAccount);
template <class T>
void
FreeItemsAndEmptyArray (
T& array)
{
for (int i = 0; i < array.GetSize(); i++)
{
delete array.GetAt(i);
}
array.RemoveAll();
}
DWORD GetCurrentUser(CString & strAccount)
{
LPBYTE pBuf;
NET_API_STATUS status = NetWkstaUserGetInfo(NULL, 1, &pBuf);
if (status == NERR_Success)
{
strAccount.Empty();
WKSTA_USER_INFO_1 * pwkstaUserInfo = (WKSTA_USER_INFO_1 *) pBuf;
strAccount = pwkstaUserInfo->wkui1_logon_domain;
strAccount += _T("\\");
strAccount += pwkstaUserInfo->wkui1_username;
NetApiBufferFree(pBuf);
}
return (DWORD) status;
}
/*!--------------------------------------------------------------------------
IsAdmin
Connect to the remote machine as administrator with user-supplied
credentials to see if the user has admin priviledges
Returns
TRUE - the user has admin rights
FALSE - if user doesn't
Author: EricDav, KennT
---------------------------------------------------------------------------*/
DWORD IsAdmin(LPCTSTR szMachineName, LPCTSTR szAccount, LPCTSTR szPassword, BOOL * pIsAdmin)
{
CString stAccount;
CString stDomain;
CString stUser;
CString stMachineName;
DWORD dwStatus;
BOOL fIsAdmin = FALSE;
// get the current user info
if (szAccount == NULL)
{
GetCurrentUser(stAccount);
}
else
{
stAccount = szAccount;
}
// separate the user and domain
int nPos = stAccount.Find(_T("\\"));
stDomain = stAccount.Left(nPos);
stUser = stAccount.Right(stAccount.GetLength() - nPos - 1);
// build the machine string
stMachineName = szMachineName;
if ( stMachineName.Left(2) != TEXT( "\\\\" ) )
{
stMachineName = TEXT( "\\\\" ) + stMachineName;
}
// validate the domain account and get the sid
PSID connectSid;
dwStatus = ValidateDomainAccount( stMachineName, stUser, stDomain, &connectSid );
if ( dwStatus != ERROR_SUCCESS )
{
goto Error;
}
// if a password was supplied, is it correct?
if (szPassword)
{
dwStatus = ValidatePassword( stUser, stDomain, szPassword );
if ( dwStatus != SEC_E_OK )
{
switch ( dwStatus )
{
case SEC_E_LOGON_DENIED:
dwStatus = ERROR_INVALID_PASSWORD;
break;
case SEC_E_INVALID_HANDLE:
dwStatus = ERROR_INTERNAL_ERROR;
break;
default:
dwStatus = ERROR_INTERNAL_ERROR;
break;
} // end of switch
goto Error;
} // Did ValidatePassword succeed?
}
// now check the machine to see if this account has admin access
fIsAdmin = IsUserAdmin( stMachineName, connectSid );
Error:
if (pIsAdmin)
*pIsAdmin = fIsAdmin;
return dwStatus;
}
BOOL
IsUserAdmin(LPCTSTR pszMachine,
PSID AccountSid)
/*++
Routine Description:
Determine if the specified account is a member of the local admin's group
Arguments:
AccountSid - pointer to service account Sid
Return Value:
True if member
--*/
{
NET_API_STATUS status;
DWORD count;
WCHAR adminGroupName[UNLEN+1];
DWORD cchName = UNLEN;
PLOCALGROUP_MEMBERS_INFO_0 grpMemberInfo;
PLOCALGROUP_MEMBERS_INFO_0 pInfo;
DWORD entriesRead;
DWORD totalEntries;
DWORD_PTR resumeHandle = NULL;
DWORD bufferSize = 128;
BOOL foundEntry = FALSE;
// get the name of the admin's group
if (!LookupAliasFromRid(NULL,
DOMAIN_ALIAS_RID_ADMINS,
adminGroupName,
&cchName)) {
return(FALSE);
}
// get the Sids of the members of the admin's group
do
{
status = NetLocalGroupGetMembers(pszMachine,
adminGroupName,
0, // level 0 - just the Sid
(LPBYTE *)&grpMemberInfo,
bufferSize,
&entriesRead,
&totalEntries,
&resumeHandle);
bufferSize *= 2;
if ( status == ERROR_MORE_DATA )
{
// we got some of the data but I want it all; free this buffer and
// reset the context handle for the API
NetApiBufferFree( grpMemberInfo );
resumeHandle = NULL;
}
} while ( status == NERR_BufTooSmall || status == ERROR_MORE_DATA );
if ( status == NERR_Success )
{
// loop through the members of the admin group, comparing the supplied
// Sid to that of the group members' Sids
for ( count = 0, pInfo = grpMemberInfo; count < totalEntries; ++count, ++pInfo )
{
if ( EqualSid( AccountSid, pInfo->lgrmi0_sid ))
{
foundEntry = TRUE;
break;
}
}
NetApiBufferFree( grpMemberInfo );
}
return foundEntry;
}
//
//
//
BOOL
LookupAliasFromRid(
LPWSTR TargetComputer,
DWORD Rid,
LPWSTR Name,
PDWORD cchName
)
{
SID_IDENTIFIER_AUTHORITY sia = SECURITY_NT_AUTHORITY;
SID_NAME_USE snu;
PSID pSid;
WCHAR DomainName[DNLEN+1];
DWORD cchDomainName = DNLEN;
BOOL bSuccess = FALSE;
//
// Sid is the same regardless of machine, since the well-known
// BUILTIN domain is referenced.
//
if(AllocateAndInitializeSid(&sia,
2,
SECURITY_BUILTIN_DOMAIN_RID,
Rid,
0, 0, 0, 0, 0, 0,
&pSid)) {
bSuccess = LookupAccountSidW(TargetComputer,
pSid,
Name,
cchName,
DomainName,
&cchDomainName,
&snu);
FreeSid(pSid);
}
return bSuccess;
} // LookupAliasFromRid
DWORD
ValidateDomainAccount(
IN CString Machine,
IN CString UserName,
IN CString Domain,
OUT PSID * AccountSid
)
/*++
Routine Description:
For the given credentials, look up the account SID for the specified
domain. As a side effect, the Sid is stored in theData->m_Sid.
Arguments:
pointers to strings that describe the user name, domain name, and password
AccountSid - address of pointer that receives the SID for this user
Return Value:
TRUE if everything validated ok.
--*/
{
DWORD dwStatus = ERROR_SUCCESS;
DWORD dwSidSize = 128;
DWORD dwDomainNameSize = 128;
LPWSTR pwszDomainName;
SID_NAME_USE SidType;
CString domainAccount;
PSID accountSid;
domainAccount = Domain + _T("\\") + UserName;
do {
// Attempt to allocate a buffer for the SID. Note that apparently in the
// absence of any error theData->m_Sid is freed only when theData goes
// out of scope.
accountSid = LocalAlloc( LMEM_FIXED, dwSidSize );
pwszDomainName = (LPWSTR) LocalAlloc( LMEM_FIXED, dwDomainNameSize * sizeof(WCHAR) );
// Was space allocated for the SID and domain name successfully?
if ( accountSid == NULL || pwszDomainName == NULL ) {
if ( accountSid != NULL ) {
LocalFree( accountSid );
}
if ( pwszDomainName != NULL ) {
LocalFree( pwszDomainName );
}
//FATALERR( IDS_ERR_NOT_ENOUGH_MEMORY, GetLastError() ); // no return
break;
}
// Attempt to Retrieve the SID and domain name. If LookupAccountName failes
// because of insufficient buffer size(s) dwSidSize and dwDomainNameSize
// will be set correctly for the next attempt.
if ( !LookupAccountName( Machine,
domainAccount,
accountSid,
&dwSidSize,
pwszDomainName,
&dwDomainNameSize,
&SidType ))
{
// free the Sid buffer and find out why we failed
LocalFree( accountSid );
dwStatus = GetLastError();
}
// domain name isn't needed at any time
LocalFree( pwszDomainName );
pwszDomainName = NULL;
} while ( dwStatus == ERROR_INSUFFICIENT_BUFFER );
if ( dwStatus == ERROR_SUCCESS ) {
*AccountSid = accountSid;
}
return dwStatus;
} // ValidateDomainAccount
NTSTATUS
ValidatePassword(
IN LPCWSTR UserName,
IN LPCWSTR Domain,
IN LPCWSTR Password
)
/*++
Routine Description:
Uses SSPI to validate the specified password
Arguments:
UserName - Supplies the user name
Domain - Supplies the user's domain
Password - Supplies the password
Return Value:
TRUE if the password is valid.
FALSE otherwise.
--*/
{
SECURITY_STATUS SecStatus;
SECURITY_STATUS AcceptStatus;
SECURITY_STATUS InitStatus;
CredHandle ClientCredHandle;
CredHandle ServerCredHandle;
BOOL ClientCredAllocated = FALSE;
BOOL ServerCredAllocated = FALSE;
CtxtHandle ClientContextHandle;
CtxtHandle ServerContextHandle;
TimeStamp Lifetime;
ULONG ContextAttributes;
PSecPkgInfo PackageInfo = NULL;
ULONG ClientFlags;
ULONG ServerFlags;
SEC_WINNT_AUTH_IDENTITY_W AuthIdentity;
SecBufferDesc NegotiateDesc;
SecBuffer NegotiateBuffer;
SecBufferDesc ChallengeDesc;
SecBuffer ChallengeBuffer;
SecBufferDesc AuthenticateDesc;
SecBuffer AuthenticateBuffer;
SecBufferDesc *pChallengeDesc = NULL;
CtxtHandle * pClientContextHandle = NULL;
CtxtHandle * pServerContextHandle = NULL;
AuthIdentity.User = (LPWSTR)UserName;
AuthIdentity.UserLength = lstrlenW(UserName);
AuthIdentity.Domain = (LPWSTR)Domain;
AuthIdentity.DomainLength = lstrlenW(Domain);
AuthIdentity.Password = (LPWSTR)Password;
AuthIdentity.PasswordLength = lstrlenW(Password);
AuthIdentity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
NegotiateBuffer.pvBuffer = NULL;
ChallengeBuffer.pvBuffer = NULL;
AuthenticateBuffer.pvBuffer = NULL;
//
// Get info about the security packages.
//
SecStatus = QuerySecurityPackageInfo( DEFAULT_SECURITY_PKG, &PackageInfo );
if ( SecStatus != STATUS_SUCCESS ) {
goto error_exit;
}
//
// Acquire a credential handle for the server side
//
SecStatus = AcquireCredentialsHandle(
NULL,
DEFAULT_SECURITY_PKG,
SECPKG_CRED_INBOUND,
NULL,
&AuthIdentity,
NULL,
NULL,
&ServerCredHandle,
&Lifetime );
if ( SecStatus != STATUS_SUCCESS ) {
goto error_exit;
}
ServerCredAllocated = TRUE;
//
// Acquire a credential handle for the client side
//
SecStatus = AcquireCredentialsHandle(
NULL, // New principal
DEFAULT_SECURITY_PKG,
SECPKG_CRED_OUTBOUND,
NULL,
&AuthIdentity,
NULL,
NULL,
&ClientCredHandle,
&Lifetime );
if ( SecStatus != STATUS_SUCCESS ) {
goto error_exit;
}
ClientCredAllocated = TRUE;
NegotiateBuffer.pvBuffer = LocalAlloc( 0, PackageInfo->cbMaxToken ); // [CHKCHK] check or allocate this earlier //
if ( NegotiateBuffer.pvBuffer == NULL ) {
SecStatus = SEC_E_INSUFFICIENT_MEMORY;
goto error_exit;
}
ChallengeBuffer.pvBuffer = LocalAlloc( 0, PackageInfo->cbMaxToken ); // [CHKCHK]
if ( ChallengeBuffer.pvBuffer == NULL ) {
SecStatus = SEC_E_INSUFFICIENT_MEMORY;
goto error_exit;
}
do {
//
// Get the NegotiateMessage (ClientSide)
//
NegotiateDesc.ulVersion = 0;
NegotiateDesc.cBuffers = 1;
NegotiateDesc.pBuffers = &NegotiateBuffer;
NegotiateBuffer.BufferType = SECBUFFER_TOKEN;
NegotiateBuffer.cbBuffer = PackageInfo->cbMaxToken;
ClientFlags = 0; // ISC_REQ_MUTUAL_AUTH | ISC_REQ_REPLAY_DETECT; // [CHKCHK] 0
InitStatus = InitializeSecurityContext(
&ClientCredHandle,
pClientContextHandle, // (NULL on the first pass, partially formed ctx on the next)
NULL, // [CHKCHK] szTargetName
ClientFlags,
0, // Reserved 1
SECURITY_NATIVE_DREP,
pChallengeDesc, // (NULL on the first pass)
0, // Reserved 2
&ClientContextHandle,
&NegotiateDesc,
&ContextAttributes,
&Lifetime );
// BUGBUG - the following call to NT_SUCCESS should be replaced with something.
if ( !NT_SUCCESS(InitStatus) ) {
SecStatus = InitStatus;
goto error_exit;
}
// ValidateBuffer( &NegotiateDesc ) // [CHKCHK]
pClientContextHandle = &ClientContextHandle;
//
// Get the ChallengeMessage (ServerSide)
//
NegotiateBuffer.BufferType |= SECBUFFER_READONLY;
ChallengeDesc.ulVersion = 0;
ChallengeDesc.cBuffers = 1;
ChallengeDesc.pBuffers = &ChallengeBuffer;
ChallengeBuffer.cbBuffer = PackageInfo->cbMaxToken;
ChallengeBuffer.BufferType = SECBUFFER_TOKEN;
ServerFlags = ASC_REQ_ALLOW_NON_USER_LOGONS; // ASC_REQ_EXTENDED_ERROR; [CHKCHK]
AcceptStatus = AcceptSecurityContext(
&ServerCredHandle,
pServerContextHandle, // (NULL on the first pass)
&NegotiateDesc,
ServerFlags,
SECURITY_NATIVE_DREP,
&ServerContextHandle,
&ChallengeDesc,
&ContextAttributes,
&Lifetime );
// BUGBUG - the following call to NT_SUCCESS should be replaced with something.
if ( !NT_SUCCESS(AcceptStatus) ) {
SecStatus = AcceptStatus;
goto error_exit;
}
// ValidateBuffer( &NegotiateDesc ) // [CHKCHK]
pChallengeDesc = &ChallengeDesc;
pServerContextHandle = &ServerContextHandle;
} while ( AcceptStatus == SEC_I_CONTINUE_NEEDED ); // || InitStatus == SEC_I_CONTINUE_NEEDED );
error_exit:
if (ServerCredAllocated) {
FreeCredentialsHandle( &ServerCredHandle );
}
if (ClientCredAllocated) {
FreeCredentialsHandle( &ClientCredHandle );
}
//
// Final Cleanup
//
if ( NegotiateBuffer.pvBuffer != NULL ) {
(VOID) LocalFree( NegotiateBuffer.pvBuffer );
}
if ( ChallengeBuffer.pvBuffer != NULL ) {
(VOID) LocalFree( ChallengeBuffer.pvBuffer );
}
if ( AuthenticateBuffer.pvBuffer != NULL ) {
(VOID) LocalFree( AuthenticateBuffer.pvBuffer );
}
return(SecStatus);
} // ValidatePassword
DEBUG_DECLARE_INSTANCE_COUNTER(CSpdInfo);
CSpdInfo::CSpdInfo() :
m_cRef(1)
{
m_Init=0;
m_Active=0;
DEBUG_INCREMENT_INSTANCE_COUNTER(CSpdInfo);
}
CSpdInfo::~CSpdInfo()
{
DEBUG_DECREMENT_INSTANCE_COUNTER(CSpdInfo);
CSingleLock cLock(&m_csData);
cLock.Lock();
//Convert the data to our internal data structure
FreeItemsAndEmptyArray(m_arrayFilters);
FreeItemsAndEmptyArray(m_arraySpecificFilters);
FreeItemsAndEmptyArray(m_arrayMmFilters);
FreeItemsAndEmptyArray(m_arrayMmSpecificFilters);
FreeItemsAndEmptyArray(m_arrayMmPolicies);
FreeItemsAndEmptyArray(m_arrMmAuthMethods);
FreeItemsAndEmptyArray(m_arrayMmSAs);
FreeItemsAndEmptyArray(m_arrayQmSAs);
FreeItemsAndEmptyArray(m_arrayQmPolicies);
cLock.Unlock();
}
// Although this object is not a COM Interface, we want to be able to
// take advantage of recounting, so we have basic addref/release/QI support
IMPLEMENT_ADDREF_RELEASE(CSpdInfo)
IMPLEMENT_SIMPLE_QUERYINTERFACE(CSpdInfo, ISpdInfo)
HRESULT CSpdInfo::SetComputerName(LPTSTR pszName)
{
m_stMachineName = pszName;
return S_OK;
}
HRESULT CSpdInfo::GetComputerName(CString * pstName)
{
Assert(pstName);
if (NULL == pstName)
return E_INVALIDARG;
*pstName = m_stMachineName;
return S_OK;
}
//Call the SPD to enum policies and put it to our array
HRESULT CSpdInfo::InternalEnumMmAuthMethods(
CMmAuthMethodsArray * pArray,
DWORD dwPreferredNum /* = 0 by default get all entries*/)
{
Assert(pArray);
HRESULT hr = hrOK;
PMM_AUTH_METHODS pAuths = NULL;
DWORD dwNumAuths = 0;
DWORD dwTemp = 0;
DWORD dwResumeHandle = 0;
FreeItemsAndEmptyArray(*pArray);
do
{
dwTemp = 0;
CWRg(::EnumMMAuthMethods(
(LPTSTR)(LPCTSTR)m_stMachineName,
&pAuths,
dwPreferredNum,
&dwTemp,
&dwResumeHandle
));
pArray->SetSize(dwNumAuths + dwTemp);
for (int i = 0; i < (int)dwTemp; i++)
{
CMmAuthMethods * pAuth = new CMmAuthMethods;
if (NULL == pAuth)
{
hr = E_OUTOFMEMORY;
break;
}
*pAuth = *(pAuths + i);
(*pArray)[dwNumAuths + i] = pAuth;
}
dwNumAuths += dwTemp;
if (pAuths)
{
SPDApiBufferFree(pAuths);
}
}while (TRUE);
// it will automatically break out from the loop when SPD returns ERROR_NO_DATA
Error:
//this particular error is because we don't have any data. Ignore it
if (HRESULT_FROM_WIN32(ERROR_NO_DATA) == hr)
hr = hrOK;
return hr;
}
HRESULT CSpdInfo::EnumMmAuthMethods()
{
HRESULT hr = hrOK;
int i;
CSingleLock cLock(&m_csData);
CMmAuthMethodsArray arrayTemp;
CORg(InternalEnumMmAuthMethods(
&arrayTemp
));
cLock.Lock();
FreeItemsAndEmptyArray(m_arrMmAuthMethods);
m_arrMmAuthMethods.Copy(arrayTemp);
Error:
//this particular error is because we don't have any MM policies. Ignore it
if (HRESULT_FROM_WIN32(ERROR_NO_DATA) == hr)
hr = hrOK;
return hr;
}
//Call the SPD to enum all Main mode SAs
HRESULT CSpdInfo::InternalEnumMmSAs(
CMmSAArray * pArray)
{
HRESULT hr = hrOK;
PIPSEC_MM_SA pSAs = NULL;
DWORD dwNumEntries = 10;
DWORD dwTotal = 0;
DWORD dwEnumHandle = 0;
IPSEC_MM_SA MMTemplate;
int i;
FreeItemsAndEmptyArray(*pArray);
memset(&MMTemplate,0,sizeof(IPSEC_MM_SA));
DWORD dwNumSAs = 0;
do
{
dwNumEntries = 10; //we request 10 (the Max#) SAs each time
CWRg(::IPSecEnumMMSAs(
(LPTSTR)(LPCTSTR)m_stMachineName,
&MMTemplate,
&pSAs,
&dwNumEntries,
&dwTotal,
&dwEnumHandle,
0 //dwFlags
));
pArray->SetSize(dwNumSAs + dwNumEntries);
for (i = 0; i < (int)dwNumEntries; i++)
{
CMmSA * psa = new CMmSA;
if (NULL == psa)
{
hr = E_OUTOFMEMORY;
break;
}
*psa = *(pSAs + i);
LoadMiscMmSAInfo(psa);
(*pArray)[dwNumSAs + i] = psa;
}
dwNumSAs += dwNumEntries;
if (pSAs)
{
SPDApiBufferFree(pSAs);
}
}while (dwTotal);
Error:
//this particular error is because we don't have any data. Ignore it
if (HRESULT_FROM_WIN32(ERROR_NO_DATA) == hr)
hr = hrOK;
return hr;
}
HRESULT CSpdInfo::EnumMmSAs()
{
HRESULT hr = hrOK;
int i;
DWORD dwCurrentIndexType = 0;
DWORD dwCurrentSortOption = 0;
CSingleLock cLock(&m_csData);
CMmSAArray arrayTemp;
CORg(InternalEnumMmSAs(
&arrayTemp
));
cLock.Lock();
FreeItemsAndEmptyArray(m_arrayMmSAs);
m_arrayMmSAs.Copy(arrayTemp);
//remember the original IndexType and Sort options
dwCurrentIndexType = m_IndexMgrMmSAs.GetCurrentIndexType();
dwCurrentSortOption = m_IndexMgrMmSAs.GetCurrentSortOption();
m_IndexMgrMmSAs.Reset();
for (i = 0; i < (int)m_arrayMmSAs.GetSize(); i++)
{
m_IndexMgrMmSAs.AddItem(m_arrayMmSAs.GetAt(i));
}
m_IndexMgrMmSAs.Sort(dwCurrentIndexType, dwCurrentSortOption);
Error:
//this particular error is because we don't have any MM policies. Ignore it
if (HRESULT_FROM_WIN32(ERROR_NO_DATA) == hr)
hr = hrOK;
return hr;
}
//Call the SPD to enum all Quick mode SAs
HRESULT CSpdInfo::InternalEnumQmSAs(
CQmSAArray * pArray)
{
HRESULT hr = hrOK;
PIPSEC_QM_SA pSAs = NULL;
DWORD dwNumEntries = 10;
DWORD dwTotal = 0;
DWORD dwResumeHandle = 0;
int i;
FreeItemsAndEmptyArray(*pArray);
DWORD dwNumSAs = 0;
do
{
CWRg(::EnumQMSAs(
(LPTSTR)(LPCTSTR)m_stMachineName,
NULL, //pMMTemplate
&pSAs,
0, //We prefer to get all
&dwNumEntries,
&dwTotal,
&dwResumeHandle,
0 //dwFlags
));
pArray->SetSize(dwNumSAs + dwNumEntries);
for (i = 0; i < (int)dwNumEntries; i++)
{
Assert(pSAs);
CQmSA * psa = new CQmSA;
if (NULL == psa)
{
hr = E_OUTOFMEMORY;
break;
}
*psa = *(pSAs + i);
LoadMiscQmSAInfo(psa);
(*pArray)[dwNumSAs + i] = psa;
}
dwNumSAs += dwNumEntries;
if (pSAs)
{
SPDApiBufferFree(pSAs);
}
}while (TRUE);
Error:
//this particular error is because we don't have any data. Ignore it
if (HRESULT_FROM_WIN32(ERROR_NO_DATA) == hr)
hr = hrOK;
return hr;
}
HRESULT CSpdInfo::EnumQmSAs()
{
HRESULT hr = hrOK;
int i;
DWORD dwCurrentIndexType = 0;
DWORD dwCurrentSortOption = 0;
CSingleLock cLock(&m_csData);
CQmSAArray arrayTemp;
CORg(InternalEnumQmSAs(
&arrayTemp
));
cLock.Lock();
FreeItemsAndEmptyArray(m_arrayQmSAs);
m_arrayQmSAs.Copy(arrayTemp);
//remember the original IndexType and Sort options
dwCurrentIndexType = m_IndexMgrQmSAs.GetCurrentIndexType();
dwCurrentSortOption = m_IndexMgrQmSAs.GetCurrentSortOption();
m_IndexMgrQmSAs.Reset();
for (i = 0; i < (int)m_arrayQmSAs.GetSize(); i++)
{
m_IndexMgrQmSAs.AddItem(m_arrayQmSAs.GetAt(i));
}
m_IndexMgrQmSAs.Sort(dwCurrentIndexType, dwCurrentSortOption);
Error:
return hr;
}
//Call the SPD to enum filters and put it to our array
HRESULT CSpdInfo::InternalEnumMmFilters(
DWORD dwLevel,
GUID guid,
CMmFilterInfoArray * pArray,
DWORD dwPreferredNum /* = 0 by default get all entries*/)
{
Assert(pArray);
HRESULT hr = hrOK;
PMM_FILTER pFilters = NULL;
DWORD dwNumFilters = 0;
DWORD dwTemp = 0;
DWORD dwResumeHandle = 0;
FreeItemsAndEmptyArray(*pArray);
do
{
dwTemp = 0;
CWRg(::EnumMMFilters(
(LPTSTR)(LPCTSTR)m_stMachineName,
dwLevel,
guid,
&pFilters,
dwPreferredNum,
&dwTemp,
&dwResumeHandle
));
pArray->SetSize(dwNumFilters + dwTemp);
for (int i = 0; i < (int)dwTemp; i++)
{
CMmFilterInfo * pFltr = new CMmFilterInfo;
if (NULL == pFltr)
{
hr = E_OUTOFMEMORY;
break;
}
*pFltr = *(pFilters + i);
LoadMiscMmFilterInfo(pFltr);
(*pArray)[dwNumFilters + i] = pFltr;
}
dwNumFilters += dwTemp;
if (pFilters)
{
SPDApiBufferFree(pFilters);
}
}while (TRUE);
// it will automatically break out from the loop when SPD returns ERROR_NO_DATA
Error:
//this particular error is because we don't have any data. Ignore it
if (HRESULT_FROM_WIN32(ERROR_NO_DATA) == hr)
hr = hrOK;
return hr;
}
HRESULT CSpdInfo::EnumMmFilters()
{
HRESULT hr = S_OK;
int i;
DWORD dwCurrentIndexType = 0;
DWORD dwCurrentSortOption = 0;
CSingleLock cLock(&m_csData);
//TODO we should either read all filters in one short
// or create some assync way to query filters
GUID guid;
ZeroMemory(&guid, sizeof(guid));
CMmFilterInfoArray arrayTempGeneric;
CMmFilterInfoArray arrayTempSpecific;
CORg(InternalEnumMmFilters(
ENUM_GENERIC_FILTERS,
guid,
&arrayTempGeneric
));
//Load the specific filters
CORg(InternalEnumMmFilters(
ENUM_SPECIFIC_FILTERS,
guid,
&arrayTempSpecific
));
cLock.Lock();
FreeItemsAndEmptyArray(m_arrayMmFilters);
m_arrayMmFilters.Copy(arrayTempGeneric);
FreeItemsAndEmptyArray(m_arrayMmSpecificFilters);
m_arrayMmSpecificFilters.Copy(arrayTempSpecific);
//remember the original IndexType and Sort options
dwCurrentIndexType = m_IndexMgrMmFilters.GetCurrentIndexType();
dwCurrentSortOption = m_IndexMgrMmFilters.GetCurrentSortOption();
m_IndexMgrMmFilters.Reset();
for (i = 0; i < m_arrayMmFilters.GetSize(); i++)
{
m_IndexMgrMmFilters.AddItem(m_arrayMmFilters.GetAt(i));
}
m_IndexMgrMmFilters.SortMmFilters(dwCurrentIndexType, dwCurrentSortOption);
//Now work on the specific filters
//remember the original IndexType and Sort options
dwCurrentIndexType = m_IndexMgrMmSpecificFilters.GetCurrentIndexType();
dwCurrentSortOption = m_IndexMgrMmSpecificFilters.GetCurrentSortOption();
m_IndexMgrMmSpecificFilters.Reset();
for (i = 0; i < m_arrayMmSpecificFilters.GetSize(); i++)
{
m_IndexMgrMmSpecificFilters.AddItem(m_arrayMmSpecificFilters.GetAt(i));
}
m_IndexMgrMmSpecificFilters.SortMmFilters(dwCurrentIndexType, dwCurrentSortOption);
Error:
return hr;
}
//Call the SPD to enum filters and put it to our array
HRESULT CSpdInfo::InternalEnumTransportFilters(
DWORD dwLevel,
GUID guid,
CFilterInfoArray * pArray,
DWORD dwPreferredNum /* = 0 by default get all entries*/)
{
Assert(pArray);
HRESULT hr = hrOK;
PTRANSPORT_FILTER pFilters = NULL;
DWORD dwNumFilters = 0;
DWORD dwTemp = 0;
DWORD dwResumeHandle = 0;
FreeItemsAndEmptyArray(*pArray);
do
{
dwTemp = 0;
CWRg(::EnumTransportFilters(
(LPTSTR)(LPCTSTR)m_stMachineName,
dwLevel,
guid,
&pFilters,
dwPreferredNum,
&dwTemp,
&dwResumeHandle
));
pArray->SetSize(dwNumFilters + dwTemp);
for (int i = 0; i < (int)dwTemp; i++)
{
CFilterInfo * pFltr = new CFilterInfo;
if (NULL == pFltr)
{
hr = E_OUTOFMEMORY;
break;
}
*pFltr = *(pFilters + i);
LoadMiscFilterInfo(pFltr);
(*pArray)[dwNumFilters + i] = pFltr;
}
dwNumFilters += dwTemp;
if (pFilters)
{
SPDApiBufferFree(pFilters);
}
}while (TRUE);
// it will automatically break out from the loop when SPD returns ERROR_NO_DATA
Error:
//this particular error is because we don't have any data. Ignore it
if (HRESULT_FROM_WIN32(ERROR_NO_DATA) == hr)
hr = hrOK;
return hr;
}
HRESULT CSpdInfo::EnumQmFilters()
{
HRESULT hr = S_OK;
int i;
DWORD dwCurrentIndexType = 0;
DWORD dwCurrentSortOption = 0;
CFilterInfoArray arrayTransportFilters;
CFilterInfoArray arrayTunnelFilters;
CFilterInfoArray arraySpTransportFilters;
CFilterInfoArray arraySpTunnelFilters;
CSingleLock cLock(&m_csData);
GUID guid;
ZeroMemory(&guid, sizeof(guid));
CORg(InternalEnumTransportFilters(
ENUM_GENERIC_FILTERS,
guid,
&arrayTransportFilters
));
CORg(InternalEnumTunnelFilters(
ENUM_GENERIC_FILTERS,
guid,
&arrayTunnelFilters
));
//We are done with the generic filters.
//Load the specific filters
CORg(InternalEnumTransportFilters(
ENUM_SPECIFIC_FILTERS,
guid,
&arraySpTransportFilters
));
CORg(InternalEnumTunnelFilters(
ENUM_SPECIFIC_FILTERS,
guid,
&arraySpTunnelFilters
));
//Update the internal data now
cLock.Lock();
FreeItemsAndEmptyArray(m_arrayFilters);
m_arrayFilters.Copy(arrayTransportFilters);
m_arrayFilters.Append(arrayTunnelFilters);
//remember the original IndexType and Sort options
dwCurrentIndexType = m_IndexMgrFilters.GetCurrentIndexType();
dwCurrentSortOption = m_IndexMgrFilters.GetCurrentSortOption();
m_IndexMgrFilters.Reset();
for (i = 0; i < (int)m_arrayFilters.GetSize(); i++)
{
m_IndexMgrFilters.AddItem(m_arrayFilters.GetAt(i));
}
m_IndexMgrFilters.SortFilters(dwCurrentIndexType, dwCurrentSortOption);
FreeItemsAndEmptyArray(m_arraySpecificFilters);
m_arraySpecificFilters.Copy(arraySpTransportFilters);
m_arraySpecificFilters.Append(arraySpTunnelFilters);
//remember the original IndexType and Sort options
dwCurrentIndexType = m_IndexMgrSpecificFilters.GetCurrentIndexType();
dwCurrentSortOption = m_IndexMgrSpecificFilters.GetCurrentSortOption();
m_IndexMgrSpecificFilters.Reset();
for (i = 0; i < (int)m_arraySpecificFilters.GetSize(); i++)
{
m_IndexMgrSpecificFilters.AddItem(m_arraySpecificFilters.GetAt(i));
}
m_IndexMgrSpecificFilters.SortFilters(dwCurrentIndexType, dwCurrentSortOption);
cLock.Unlock();
Error:
//this particular error is because we don't have any MM policies. Ignore it
if (HRESULT_FROM_WIN32(ERROR_NO_DATA) == hr)
hr = hrOK;
return hr;
}
//Call the SPD to enum filters and put it to our array
HRESULT CSpdInfo::InternalEnumTunnelFilters(
DWORD dwLevel,
GUID guid,
CFilterInfoArray * pArray,
DWORD dwPreferredNum /* = 0 by default get all entries*/)
{
Assert(pArray);
HRESULT hr = hrOK;
FreeItemsAndEmptyArray(*pArray);
PTUNNEL_FILTER pFilters = NULL;
DWORD dwNumFilters = 0;
DWORD dwTemp = 0;
DWORD dwResumeHandle = 0;
do
{
dwTemp = 0;
CWRg(::EnumTunnelFilters(
(LPTSTR)(LPCTSTR)m_stMachineName,
dwLevel,
guid,
&pFilters,
dwPreferredNum,
&dwTemp,
&dwResumeHandle
));
pArray->SetSize(dwNumFilters + dwTemp);
for (int i = 0; i < (int)dwTemp; i++)
{
CFilterInfo * pFltr = new CFilterInfo;
if (NULL == pFltr)
{
hr = E_OUTOFMEMORY;
break;
}
*pFltr = *(pFilters + i);
LoadMiscFilterInfo(pFltr);
(*pArray)[dwNumFilters + i] = pFltr;
}
dwNumFilters += dwTemp;
if (pFilters)
{
SPDApiBufferFree(pFilters);
}
}while (TRUE);
// it will automatically break out from the loop when SPD returns ERROR_NO_DATA
Error:
//this particular error is because we don't have any data. Ignore it
if (HRESULT_FROM_WIN32(ERROR_NO_DATA) == hr)
hr = hrOK;
return hr;
}
HRESULT CSpdInfo::EnumSpecificFilters
(
GUID * pFilterGuid,
CFilterInfoArray * parraySpecificFilters,
FILTER_TYPE fltrType
)
{
Assert (pFilterGuid);
Assert (parraySpecificFilters);
HRESULT hr = hrOK;
int i;
if (FILTER_TYPE_TUNNEL == fltrType)
{
CORg(InternalEnumTunnelFilters(
ENUM_SELECT_SPECIFIC_FILTERS,
*pFilterGuid,
parraySpecificFilters
));
}
else if (FILTER_TYPE_TRANSPORT == fltrType)
{
CORg(InternalEnumTransportFilters(
ENUM_SELECT_SPECIFIC_FILTERS,
*pFilterGuid,
parraySpecificFilters
));
}
Error:
//this particular error is because we don't have any MM policies. Ignore it
if (HRESULT_FROM_WIN32(ERROR_NO_DATA) == hr)
hr = hrOK;
return hr;
}
//Convert internal filter data to external spd data structure
//NOTE: the routine only convert severl parameters that are
//needed for searching match filters
void CSpdInfo::ConvertToExternalFilterData
(
CFilterInfo * pfltrIn,
TRANSPORT_FILTER * pfltrOut
)
{
ZeroMemory (pfltrOut, sizeof(*pfltrOut));
//pfltrOut->bCreateMirror = pfltrIn->m_bCreateMirror;
pfltrOut->DesAddr = pfltrIn->m_DesAddr;
pfltrOut->DesPort = pfltrIn->m_DesPort;
pfltrOut->dwDirection = pfltrIn->m_dwDirection;
//pfltrOut->dwWeight = pfltrIn->m_dwWeight;
//pfltrOut->FilterFlag = pfltrIn->;
//pfltrOut->gFilterID = pfltrIn->m_guidFltr;
//pfltrOut->gPolicyID = pfltrIn->m_guidPolicyID;
//pfltrOut->InterfaceType = pfltrIn->m_InterfaceType;
pfltrOut->Protocol = pfltrIn->m_Protocol;
pfltrOut->SrcAddr = pfltrIn->m_SrcAddr;
pfltrOut->SrcPort = pfltrIn->m_SrcPort;
}
HRESULT CSpdInfo::GetMatchFilters
(
CFilterInfo * pfltrSearchCondition,
DWORD dwPreferredNum,
CFilterInfoArray * parrFilters
)
{
HRESULT hr = S_OK;
Assert (pfltrSearchCondition);
Assert (parrFilters);
PTRANSPORT_FILTER pMatchedFilters = NULL;
PIPSEC_QM_POLICY pMatchedPolicies = NULL;
DWORD dwNumMatches = 0;
DWORD dwResumeHandle = 0;
DWORD i = 0;
TRANSPORT_FILTER SpdFltr;
ConvertToExternalFilterData(pfltrSearchCondition, &SpdFltr);
CWRg(::MatchTransportFilter (
(LPTSTR)((LPCTSTR)m_stMachineName),
&SpdFltr,
0, //Don't return default policy if no match
&pMatchedFilters,
&pMatchedPolicies,
dwPreferredNum, //enum all //BUGBUG should be 0 instead of 1000
&dwNumMatches,
&dwResumeHandle
));
//Todo check whether we really got all.
parrFilters->SetSize(dwNumMatches);
for (i = 0; i < dwNumMatches; i++)
{
CFilterInfo * pFltr = new CFilterInfo;
*pFltr = *(pMatchedFilters + i);
LoadMiscFilterInfo(pFltr);
(*parrFilters)[i] = pFltr;
}
if (pMatchedFilters)
SPDApiBufferFree(pMatchedFilters);
if (pMatchedPolicies)
SPDApiBufferFree(pMatchedPolicies);
Error:
//this particular error is because we don't have any data. Ignore it
if (HRESULT_FROM_WIN32(ERROR_NO_DATA) == hr)
hr = hrOK;
return hr;
}
//Convert internal filter data to external spd data structure
//NOTE: the routine only convert severl parameters that are
//needed for searching match filters
void CSpdInfo::ConvertToExternalMMFilterData
(
CMmFilterInfo * pfltrIn,
MM_FILTER * pfltrOut
)
{
ZeroMemory (pfltrOut, sizeof(*pfltrOut));
//pfltrOut->bCreateMirror = pfltrIn->m_bCreateMirror;
pfltrOut->DesAddr = pfltrIn->m_DesAddr;
pfltrOut->dwDirection = pfltrIn->m_dwDirection;
//pfltrOut->dwWeight = pfltrIn->m_dwWeight;
//pfltrOut->gFilterID = pfltrIn->m_guidFltr;
//pfltrOut->gPolicyID = pfltrIn->m_guidPolicyID;
//pfltrOut->InterfaceType = pfltrIn->m_InterfaceType;
pfltrOut->SrcAddr = pfltrIn->m_SrcAddr;
}
HRESULT CSpdInfo::GetMatchMMFilters
(
CMmFilterInfo * pfltrSearchCondition,
DWORD dwPreferredNum,
CMmFilterInfoArray * parrFilters
)
{
HRESULT hr = S_OK;
Assert (pfltrSearchCondition);
Assert (parrFilters);
PMM_FILTER pMatchedFilters = NULL;
PIPSEC_MM_POLICY pMatchedPolicies = NULL;
PMM_AUTH_METHODS pMatchedAuths = NULL;
DWORD dwNumMatches = 0;
DWORD dwResumeHandle = 0;
DWORD i = 0;
MM_FILTER SpdFltr;
ConvertToExternalMMFilterData(pfltrSearchCondition, &SpdFltr);
CWRg(::MatchMMFilter (
(LPTSTR)((LPCTSTR)m_stMachineName),
&SpdFltr,
0, //Don't return default policy if no match
&pMatchedFilters,
&pMatchedPolicies,
&pMatchedAuths,
dwPreferredNum, //enum all //TODO BUGBUG should be 0 instead of 1000
&dwNumMatches,
&dwResumeHandle
));
//Todo check whether we really got all.
parrFilters->SetSize(dwNumMatches);
for (i = 0; i < dwNumMatches; i++)
{
CMmFilterInfo * pFltr = new CMmFilterInfo;
*pFltr = *(pMatchedFilters + i);
LoadMiscMmFilterInfo(pFltr);
(*parrFilters)[i] = pFltr;
}
if (pMatchedFilters)
SPDApiBufferFree(pMatchedFilters);
if (pMatchedPolicies)
SPDApiBufferFree(pMatchedPolicies);
if (pMatchedAuths)
SPDApiBufferFree(pMatchedAuths);
Error:
//this particular error is because we don't have any data. Ignore it
if (HRESULT_FROM_WIN32(ERROR_NO_DATA) == hr)
hr = hrOK;
return hr;
}
HRESULT CSpdInfo::EnumMmSpecificFilters
(
GUID * pGenFilterGuid,
CMmFilterInfoArray * parraySpecificFilters
)
{
Assert (pGenFilterGuid);
Assert (parraySpecificFilters);
HRESULT hr = hrOK;
DWORD dwNumFilters = 0;
DWORD dwResumeHandle = 0;
int i;
parraySpecificFilters->RemoveAll();
CORg(InternalEnumMmFilters(
ENUM_SELECT_SPECIFIC_FILTERS,
*pGenFilterGuid,
parraySpecificFilters
));
Error:
//this particular error is because we don't have any MM policies. Ignore it
if (HRESULT_FROM_WIN32(ERROR_NO_DATA) == hr)
hr = hrOK;
return hr;
}
//Call the SPD to enum policies and put it to our array
HRESULT CSpdInfo::InternalEnumMmPolicies(
CMmPolicyInfoArray * pArray,
DWORD dwPreferredNum /* = 0 by default get all entries*/)
{
Assert(pArray);
HRESULT hr = hrOK;
PIPSEC_MM_POLICY pPolicies = NULL;
DWORD dwNumPolicies = 0;
DWORD dwTemp = 0;
DWORD dwResumeHandle = 0;
FreeItemsAndEmptyArray(*pArray);
do
{
dwTemp = 0;
CWRg(::EnumMMPolicies(
(LPTSTR)(LPCTSTR)m_stMachineName,
&pPolicies,
dwPreferredNum,
&dwTemp,
&dwResumeHandle
));
pArray->SetSize(dwNumPolicies + dwTemp);
for (int i = 0; i < (int)dwTemp; i++)
{
CMmPolicyInfo * pPol = new CMmPolicyInfo;
if (NULL == pPol)
{
hr = E_OUTOFMEMORY;
break;
}
*pPol = *(pPolicies + i);
(*pArray)[dwNumPolicies + i] = pPol;
}
dwNumPolicies += dwTemp;
if (pPolicies)
{
SPDApiBufferFree(pPolicies);
}
}while (TRUE);
// it will automatically break out from the loop when SPD returns ERROR_NO_DATA
Error:
//this particular error is because we don't have any data. Ignore it
if (HRESULT_FROM_WIN32(ERROR_NO_DATA) == hr)
hr = hrOK;
return hr;
}
HRESULT CSpdInfo::EnumMmPolicies()
{
HRESULT hr = hrOK;
CSingleLock cLock(&m_csData);
DWORD dwCurrentIndexType;
DWORD dwCurrentSortOption;
int i;
CMmPolicyInfoArray arrayTemp;
CORg(InternalEnumMmPolicies(
&arrayTemp,
0 //enum all policies
));
cLock.Lock();
FreeItemsAndEmptyArray(m_arrayMmPolicies);
m_arrayMmPolicies.Copy(arrayTemp);
//remember the original IndexType and Sort options
dwCurrentIndexType = m_IndexMgrMmPolicies.GetCurrentIndexType();
dwCurrentSortOption = m_IndexMgrMmPolicies.GetCurrentSortOption();
m_IndexMgrMmPolicies.Reset();
for (i = 0; i < (int)m_arrayMmPolicies.GetSize(); i++)
{
m_IndexMgrMmPolicies.AddItem(m_arrayMmPolicies.GetAt(i));
}
m_IndexMgrMmPolicies.Sort(dwCurrentIndexType, dwCurrentSortOption);
Error:
//this particular error is because we don't have any MM policies. Ignore it
if (HRESULT_FROM_WIN32(ERROR_NO_DATA) == hr)
hr = hrOK;
return hr;
}
//Call the SPD to enum policies and put it to our array
HRESULT CSpdInfo::InternalEnumQmPolicies(
CQmPolicyInfoArray * pArray,
DWORD dwPreferredNum /* = 0 by default get all entries*/)
{
Assert(pArray);
HRESULT hr = hrOK;
PIPSEC_QM_POLICY pPolicies = NULL;
DWORD dwNumPolicies = 0;
DWORD dwTemp = 0;
DWORD dwResumeHandle = 0;
FreeItemsAndEmptyArray(*pArray);
do
{
dwTemp = 0;
CWRg(::EnumQMPolicies(
(LPTSTR)(LPCTSTR)m_stMachineName,
&pPolicies,
dwPreferredNum,
&dwTemp,
&dwResumeHandle
));
pArray->SetSize(dwNumPolicies + dwTemp);
for (int i = 0; i < (int)dwTemp; i++)
{
CQmPolicyInfo * pPol = new CQmPolicyInfo;
if (NULL == pPol)
{
hr = E_OUTOFMEMORY;
break;
}
*pPol = *(pPolicies + i);
(*pArray)[dwNumPolicies + i] = pPol;
}
dwNumPolicies += dwTemp;
if (pPolicies)
{
SPDApiBufferFree(pPolicies);
}
}while (TRUE);
// it will automatically break out from the loop when SPD returns ERROR_NO_DATA
Error:
//this particular error is because we don't have any data. Ignore it
if (HRESULT_FROM_WIN32(ERROR_NO_DATA) == hr)
hr = hrOK;
return hr;
}
HRESULT CSpdInfo::EnumQmPolicies()
{
HRESULT hr = hrOK;
CSingleLock cLock(&m_csData);
DWORD dwCurrentIndexType;
DWORD dwCurrentSortOption;
int i;
CQmPolicyInfoArray arrayTemp;
CORg(InternalEnumQmPolicies(
&arrayTemp
));
cLock.Lock();
FreeItemsAndEmptyArray(m_arrayQmPolicies);
m_arrayQmPolicies.Copy(arrayTemp);
//remember the original IndexType and Sort options
dwCurrentIndexType = m_IndexMgrQmPolicies.GetCurrentIndexType();
dwCurrentSortOption = m_IndexMgrQmPolicies.GetCurrentSortOption();
m_IndexMgrQmPolicies.Reset();
for (i = 0; i < (int)m_arrayQmPolicies.GetSize(); i++)
{
m_IndexMgrQmPolicies.AddItem(m_arrayQmPolicies.GetAt(i));
}
m_IndexMgrQmPolicies.Sort(dwCurrentIndexType, dwCurrentSortOption);
Error:
//this particular error is because we don't have any QM policies. Ignore it
if (HRESULT_FROM_WIN32(ERROR_NO_DATA) == hr)
hr = hrOK;
return hr;
}
DWORD CSpdInfo::GetMmAuthMethodsCount()
{
CSingleLock cLock(&m_csData);
cLock.Lock();
return (DWORD)m_arrMmAuthMethods.GetSize();
}
DWORD CSpdInfo::GetMmSACount()
{
CSingleLock cLock(&m_csData);
cLock.Lock();
return (DWORD)m_arrayMmSAs.GetSize();
}
DWORD CSpdInfo::GetMmPolicyCount()
{
CSingleLock cLock(&m_csData);
cLock.Lock();
return (DWORD)m_arrayMmPolicies.GetSize();
}
DWORD CSpdInfo::GetQmSACount()
{
CSingleLock cLock(&m_csData);
cLock.Lock();
return (DWORD)m_arrayQmSAs.GetSize();
}
DWORD CSpdInfo::GetQmPolicyCount()
{
CSingleLock cLock(&m_csData);
cLock.Lock();
return (DWORD)m_arrayQmPolicies.GetSize();
}
DWORD CSpdInfo::GetQmFilterCountOfCurrentViewType()
{
CSingleLock cLock(&m_csData);
cLock.Lock();
return (DWORD)(m_IndexMgrFilters.GetItemCount());
}
DWORD CSpdInfo::GetQmSpFilterCountOfCurrentViewType()
{
CSingleLock cLock(&m_csData);
cLock.Lock();
return (DWORD)(m_IndexMgrSpecificFilters.GetItemCount());
}
DWORD CSpdInfo::GetMmFilterCount()
{
CSingleLock cLock(&m_csData);
cLock.Lock();
return (DWORD)(m_arrayMmFilters.GetSize());
}
DWORD CSpdInfo::GetMmSpecificFilterCount()
{
CSingleLock cLock(&m_csData);
cLock.Lock();
return (DWORD)(m_arrayMmSpecificFilters.GetSize());
}
HRESULT CSpdInfo::GetFilterInfo(int iIndex, CFilterInfo * pFilter)
{
HRESULT hr = S_OK;
Assert(pFilter);
if (NULL == pFilter)
return E_INVALIDARG;
CSingleLock cLock(&m_csData);
cLock.Lock();
if (iIndex < m_arrayFilters.GetSize())
{
CFilterInfo * pFltrData = (CFilterInfo*)m_IndexMgrFilters.GetItemData(iIndex);
Assert(pFltrData);
*pFilter = *pFltrData;
}
else
{
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
}
return hr;
}
HRESULT CSpdInfo::GetSpecificFilterInfo(int iIndex, CFilterInfo * pFilter)
{
HRESULT hr = S_OK;
Assert(pFilter);
if (NULL == pFilter)
return E_INVALIDARG;
CSingleLock cLock(&m_csData);
cLock.Lock();
if (iIndex < m_arraySpecificFilters.GetSize())
{
CFilterInfo * pFltrData = (CFilterInfo*)m_IndexMgrSpecificFilters.GetItemData(iIndex);
Assert(pFltrData);
*pFilter = *pFltrData;
}
else
{
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
}
return hr;
}
HRESULT CSpdInfo::GetMmFilterInfo(int iIndex, CMmFilterInfo * pFltr)
{
HRESULT hr = S_OK;
Assert(pFltr);
if (NULL == pFltr)
return E_INVALIDARG;
CSingleLock cLock(&m_csData);
cLock.Lock();
if (iIndex < m_arrayMmFilters.GetSize())
{
CMmFilterInfo * pFltrData = (CMmFilterInfo*)m_IndexMgrMmFilters.GetItemData(iIndex);
Assert(pFltrData);
*pFltr = *pFltrData;
}
else
{
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
}
return hr;
}
HRESULT CSpdInfo::GetMmSpecificFilterInfo
(
int iIndex,
CMmFilterInfo * pFltr
)
{
HRESULT hr = S_OK;
Assert(pFltr);
if (NULL == pFltr)
return E_INVALIDARG;
CSingleLock cLock(&m_csData);
cLock.Lock();
if (iIndex < m_arrayMmSpecificFilters.GetSize())
{
CMmFilterInfo * pFltrData = (CMmFilterInfo*)m_IndexMgrMmSpecificFilters.GetItemData(iIndex);
Assert(pFltrData);
*pFltr = *pFltrData;
}
else
{
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
}
return hr;
}
HRESULT CSpdInfo::GetMmPolicyInfo(int iIndex, CMmPolicyInfo * pMmPolicy)
{
HRESULT hr = hrOK;
Assert(pMmPolicy);
if (NULL == pMmPolicy)
return E_INVALIDARG;
CSingleLock cLock(&m_csData);
cLock.Lock();
if (iIndex < m_arrayMmPolicies.GetSize())
{
CMmPolicyInfo * pPolicy = (CMmPolicyInfo*) m_IndexMgrMmPolicies.GetItemData(iIndex);
*pMmPolicy = *pPolicy;
}
else
{
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
}
return hr;
}
HRESULT CSpdInfo::GetMmAuthMethodsInfo(int iIndex, CMmAuthMethods * pMmAuth)
{
HRESULT hr = hrOK;
CSingleLock cLock(&m_csData);
cLock.Lock();
if (iIndex < m_arrMmAuthMethods.GetSize())
{
*pMmAuth = *m_arrMmAuthMethods[iIndex];
}
else
{
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
}
return hr;
}
HRESULT CSpdInfo::GetMmSAInfo(int iIndex, CMmSA * pSA)
{
HRESULT hr = hrOK;
CSingleLock cLock(&m_csData);
cLock.Lock();
Assert(pSA);
if (NULL == pSA)
return E_INVALIDARG;
if (iIndex < m_arrayMmSAs.GetSize())
{
CMmSA * pSATemp = (CMmSA*) m_IndexMgrMmSAs.GetItemData(iIndex);
*pSA = *pSATemp;
}
else
{
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
}
return hr;
}
HRESULT CSpdInfo::GetQmSAInfo(int iIndex, CQmSA * pSA)
{
HRESULT hr = hrOK;
CSingleLock cLock(&m_csData);
cLock.Lock();
Assert(pSA);
if (NULL == pSA)
return E_INVALIDARG;
if (iIndex < m_arrayQmSAs.GetSize())
{
CQmSA * pSATemp = (CQmSA*) m_IndexMgrQmSAs.GetItemData(iIndex);
*pSA = *pSATemp;
}
else
{
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
}
return hr;
}
HRESULT CSpdInfo::GetQmPolicyInfo(int iIndex, CQmPolicyInfo * pQmPolicy)
{
HRESULT hr = hrOK;
if (NULL == pQmPolicy)
return E_INVALIDARG;
CSingleLock cLock(&m_csData);
cLock.Lock();
if (iIndex < m_arrayQmPolicies.GetSize())
{
CQmPolicyInfo * pPolicy = (CQmPolicyInfo*) m_IndexMgrQmPolicies.GetItemData(iIndex);
*pQmPolicy = *pPolicy;
}
else
{
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
}
return hr;
}
HRESULT CSpdInfo::GetQmPolicyNameByGuid(GUID guid, CString * pst)
{
HRESULT hr = hrOK;
if (NULL == pst)
return E_INVALIDARG;
pst->Empty();
PIPSEC_QM_POLICY pPolicy = NULL;
CWRg(::GetQMPolicyByID(
(LPTSTR)(LPCTSTR) m_stMachineName,
guid,
&pPolicy));
if (pPolicy)
{
*pst = pPolicy->pszPolicyName;
SPDApiBufferFree(pPolicy);
}
else
{
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
}
Error:
return hr;
}
HRESULT CSpdInfo::GetMmPolicyNameByGuid(GUID guid, CString * pst)
{
HRESULT hr = hrOK;
if (NULL == pst)
return E_INVALIDARG;
pst->Empty();
PIPSEC_MM_POLICY pPolicy = NULL;
CWRg(::GetMMPolicyByID(
(LPTSTR)(LPCTSTR) m_stMachineName,
guid,
&pPolicy));
if (pPolicy)
{
*pst = pPolicy->pszPolicyName;
SPDApiBufferFree(pPolicy);
}
else
{
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
}
Error:
return hr;
}
HRESULT CSpdInfo::GetMmAuthMethodsInfoByGuid(GUID guid, CMmAuthMethods * pMmAuth)
{
HRESULT hr = hrOK;
PMM_AUTH_METHODS pSpdAuth = NULL;
CWRg(::GetMMAuthMethods(
(LPTSTR)(LPCTSTR) m_stMachineName,
guid,
&pSpdAuth));
if (pSpdAuth)
{
*pMmAuth = *pSpdAuth;
SPDApiBufferFree(pSpdAuth);
}
else
{
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
}
Error:
return hr;
}
HRESULT CSpdInfo::SortFilters(DWORD dwIndexType, DWORD dwSortOptions)
{
return m_IndexMgrFilters.SortFilters(dwIndexType, dwSortOptions);
}
HRESULT CSpdInfo::SortSpecificFilters(DWORD dwIndexType, DWORD dwSortOptions)
{
return m_IndexMgrSpecificFilters.SortFilters(dwIndexType, dwSortOptions);
}
HRESULT CSpdInfo::SortMmFilters(DWORD dwIndexType, DWORD dwSortOptions)
{
return m_IndexMgrMmFilters.SortMmFilters(dwIndexType, dwSortOptions);
}
HRESULT CSpdInfo::SortMmSpecificFilters(DWORD dwIndexType, DWORD dwSortOptions)
{
return m_IndexMgrMmSpecificFilters.SortMmFilters(dwIndexType, dwSortOptions);
}
HRESULT CSpdInfo::SortMmPolicies(DWORD dwIndexType, DWORD dwSortOptions)
{
return m_IndexMgrMmPolicies.Sort(dwIndexType, dwSortOptions);
}
HRESULT CSpdInfo::SortQmPolicies(DWORD dwIndexType, DWORD dwSortOptions)
{
return m_IndexMgrQmPolicies.Sort(dwIndexType, dwSortOptions);
}
HRESULT CSpdInfo::SortMmSAs(DWORD dwIndexType, DWORD dwSortOptions)
{
return m_IndexMgrMmSAs.Sort(dwIndexType, dwSortOptions);
}
HRESULT CSpdInfo::SortQmSAs(DWORD dwIndexType, DWORD dwSortOptions)
{
return m_IndexMgrQmSAs.Sort(dwIndexType, dwSortOptions);
}
HRESULT CSpdInfo::EnumQmSAsFromMmSA(const CMmSA & MmSA, CQmSAArray * parrayQmSAs)
{
HRESULT hr = hrOK;
if (NULL == parrayQmSAs)
return E_INVALIDARG;
FreeItemsAndEmptyArray(*parrayQmSAs);
for (int i = 0; i < m_arrayQmSAs.GetSize(); i++)
{
if (0 == memcmp(&MmSA.m_MMSpi, &(m_arrayQmSAs[i]->m_MMSpi), sizeof(MmSA.m_MMSpi)))
{
CQmSA * pSA = new CQmSA;
if (NULL == pSA)
{
FreeItemsAndEmptyArray(*parrayQmSAs);
hr = E_OUTOFMEMORY;
break;
}
*pSA = *(m_arrayQmSAs[i]);
parrayQmSAs->Add(pSA);
}
}
return hr;
}
HRESULT CSpdInfo::LoadStatistics()
{
HRESULT hr;
PIPSEC_STATISTICS pIpsecStats = NULL;
IKE_STATISTICS ikeStats;
ZeroMemory(&ikeStats, sizeof(ikeStats));
CWRg(::IPSecQueryIKEStatistics((LPTSTR)(LPCTSTR)m_stMachineName,
&ikeStats));
m_IkeStats = ikeStats;
CWRg(::QueryIPSecStatistics((LPTSTR)(LPCTSTR)m_stMachineName,
&pIpsecStats));
Assert(pIpsecStats);
m_IpsecStats = *pIpsecStats;
if (pIpsecStats)
{
SPDApiBufferFree(pIpsecStats);
}
Error:
return hr;
}
// Get the current cached statistics
void CSpdInfo::GetLoadedStatistics(CIkeStatistics * pIkeStats, CIpsecStatistics * pIpsecStats)
{
if (pIkeStats)
{
*pIkeStats = m_IkeStats;
}
if (pIpsecStats)
{
*pIpsecStats = m_IpsecStats;
}
}
void CSpdInfo::ChangeQmFilterViewType(FILTER_TYPE FltrType)
{
CSingleLock cLock(&m_csData);
cLock.Lock();
DWORD dwCurrentIndexType = m_IndexMgrFilters.GetCurrentIndexType();
DWORD dwCurrentSortOption = m_IndexMgrFilters.GetCurrentSortOption();
m_IndexMgrFilters.Reset();
for (int i = 0; i < m_arrayFilters.GetSize(); i++)
{
if (FILTER_TYPE_ANY == FltrType ||
FltrType == m_arrayFilters[i]->m_FilterType)
{
m_IndexMgrFilters.AddItem(m_arrayFilters.GetAt(i));
}
}
m_IndexMgrFilters.SortFilters(dwCurrentIndexType, dwCurrentSortOption);
}
void CSpdInfo::ChangeQmSpFilterViewType(FILTER_TYPE FltrType)
{
CSingleLock cLock(&m_csData);
cLock.Lock();
DWORD dwCurrentIndexType = m_IndexMgrSpecificFilters.GetCurrentIndexType();
DWORD dwCurrentSortOption = m_IndexMgrSpecificFilters.GetCurrentSortOption();
m_IndexMgrSpecificFilters.Reset();
for (int i = 0; i < m_arraySpecificFilters.GetSize(); i++)
{
if (FILTER_TYPE_ANY == FltrType ||
FltrType == m_arraySpecificFilters[i]->m_FilterType)
{
m_IndexMgrSpecificFilters.AddItem(m_arraySpecificFilters.GetAt(i));
}
}
m_IndexMgrSpecificFilters.SortFilters(dwCurrentIndexType, dwCurrentSortOption);
}
HRESULT CSpdInfo::LoadMiscMmSAInfo(CMmSA * pSA)
{
Assert(pSA);
return GetMmPolicyNameByGuid(pSA->m_guidPolicy, &pSA->m_stPolicyName);
}
HRESULT CSpdInfo::LoadMiscQmSAInfo(CQmSA * pSA)
{
Assert(pSA);
return GetQmPolicyNameByGuid(pSA->m_guidPolicy, &pSA->m_stPolicyName);
}
HRESULT CSpdInfo::LoadMiscFilterInfo(CFilterInfo * pFltr)
{
Assert(pFltr);
return GetQmPolicyNameByGuid(pFltr->m_guidPolicyID, &pFltr->m_stPolicyName);
}
HRESULT CSpdInfo::LoadMiscMmFilterInfo(CMmFilterInfo * pFltr)
{
Assert(pFltr);
HRESULT hr = S_OK;
HRESULT hrTemp;
CMmAuthMethods auth;
hrTemp = GetMmAuthMethodsInfoByGuid(pFltr->m_guidAuthID, &auth);
if (FAILED(hrTemp))
hr = hrTemp;
pFltr->m_stAuthDescription = auth.m_stDescription;
hrTemp = GetMmPolicyNameByGuid(pFltr->m_guidPolicyID, &pFltr->m_stPolicyName);
if (FAILED(hrTemp))
hr = hrTemp;
return hr;
}
STDMETHODIMP
CSpdInfo::Destroy()
{
//$REVIEW this routine get called when doing auto-refresh
//We don't need to clean up anything at this time.
//Each array (Filter, SA, policy...) will get cleaned up when calling the
//corresponding enum function.
return S_OK;
}
DWORD
CSpdInfo::GetInitInfo()
{
CSingleLock cLock(&m_csData);
cLock.Lock();
return m_Init;
}
void
CSpdInfo::SetInitInfo(DWORD dwInitInfo)
{
CSingleLock cLock(&m_csData);
cLock.Lock();
m_Init=dwInitInfo;
}
DWORD
CSpdInfo::GetActiveInfo()
{
CSingleLock cLock(&m_csData);
cLock.Lock();
return m_Active;
}
void
CSpdInfo::SetActiveInfo(DWORD dwActiveInfo)
{
CSingleLock cLock(&m_csData);
cLock.Lock();
m_Active=dwActiveInfo;
}
/*!--------------------------------------------------------------------------
CreateSpdInfo
Helper to create the SpdInfo object.
---------------------------------------------------------------------------*/
HRESULT
CreateSpdInfo(ISpdInfo ** ppSpdInfo)
{
AFX_MANAGE_STATE(AfxGetModuleState());
SPISpdInfo spSpdInfo;
ISpdInfo * pSpdInfo = NULL;
HRESULT hr = hrOK;
COM_PROTECT_TRY
{
pSpdInfo = new CSpdInfo;
// Do this so that it will get freed on error
spSpdInfo = pSpdInfo;
*ppSpdInfo = spSpdInfo.Transfer();
}
COM_PROTECT_CATCH
return hr;
}
//
// FUNCTIONS: MIDL_user_allocate and MIDL_user_free
//
// PURPOSE: Used by stubs to allocate and free memory
// in standard RPC calls. Not used when
// [enable_allocate] is specified in the .acf.
//
//
// PARAMETERS:
// See documentations.
//
// RETURN VALUE:
// Exceptions on error. This is not required,
// you can use -error allocation on the midl.exe
// command line instead.
//
//
void * __RPC_USER MIDL_user_allocate(size_t size)
{
return(HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, size));
}
void __RPC_USER MIDL_user_free( void *pointer)
{
HeapFree(GetProcessHeap(), 0, pointer);
}