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.
1631 lines
39 KiB
1631 lines
39 KiB
/**********************************************************************/
|
|
/** 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 MAX_NUM_RECORDS 10 // was 10
|
|
|
|
#define DEFAULT_SECURITY_PKG _T("negotiate")
|
|
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
|
|
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
|
|
|
|
//
|
|
// The database holds 5K records and wraps around. So we dont cache more than
|
|
// 5K records.
|
|
//
|
|
|
|
#define WZCDB_DEFAULT_NUM_RECS 5000
|
|
// 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);
|
|
|
|
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),
|
|
m_session_init(false),
|
|
m_dwSortIndex(IDS_COL_LOGDATA_TIME),
|
|
m_dwSortOption(SORT_ASCENDING),
|
|
m_nNumRecords(WZCDB_DEFAULT_NUM_RECS),
|
|
m_bEliminateDuplicates(FALSE)
|
|
|
|
{
|
|
HRESULT hr = S_OK;
|
|
HANDLE hSession = NULL;
|
|
|
|
/*
|
|
Either we opened a session successfully or we found out that logging
|
|
is disabled. If logging is disabled then we check every time EnumLogData
|
|
is called to see if we can access the database.
|
|
*/
|
|
|
|
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_arrayFWFilters);
|
|
FreeItemsAndEmptyArray(m_arrayLogData);
|
|
|
|
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)
|
|
|
|
|
|
void
|
|
CSpdInfo::FreeItemsAndEmptyArray(
|
|
CLogDataInfoArray& array
|
|
)
|
|
{
|
|
for (int i = 0; i < array.GetSize(); i++)
|
|
{
|
|
delete array.GetAt(i);
|
|
}
|
|
array.RemoveAll();
|
|
}
|
|
|
|
|
|
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;
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CSpdInfo::GetSession(
|
|
PHANDLE phsession
|
|
)
|
|
{
|
|
Assert(session);
|
|
|
|
if (NULL == phsession)
|
|
return E_INVALIDARG;
|
|
|
|
*phsession = m_session;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CSpdInfo::SetSession(
|
|
HANDLE hsession
|
|
)
|
|
{
|
|
m_csData.Lock();
|
|
|
|
m_session = hsession;
|
|
m_session_init = true;
|
|
m_bFromFirst = TRUE;
|
|
|
|
m_csData.Unlock();
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CSpdInfo::ResetSession()
|
|
/*++
|
|
CSpdInfo::ResetSession:
|
|
Used to reset the session when the logging is turned off so that we dont
|
|
use a bad session.
|
|
|
|
Arguments:
|
|
None
|
|
|
|
Returns:
|
|
Always returns S_OK
|
|
--*/
|
|
{
|
|
if (m_session != NULL)
|
|
CloseWZCDbLogSession(m_session);
|
|
|
|
m_session = NULL;
|
|
m_session_init = false;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
DWORD
|
|
CSpdInfo::EliminateDuplicates(
|
|
CLogDataInfoArray *pArray
|
|
)
|
|
/*++
|
|
CSpdInfo::EliminateDuplicates: Removes duplicate records from the given
|
|
array.
|
|
|
|
If the database moves past the end of the table, it cannot move
|
|
to get new records on the next refresh cyle, hence it always remains
|
|
on the last record. So if our cache size is the same as the database
|
|
size, then we must delete the first record as the new enumeration
|
|
would have resulted in a duplicate record.
|
|
|
|
We also know that in only the first element is a duplicate
|
|
|
|
Arguments:
|
|
[in/out] pArray - Pointer to array containing elements. On exit contains
|
|
all non duplicate elements
|
|
|
|
Returns:
|
|
ERROR_SUCCESS on success
|
|
--*/
|
|
{
|
|
int i = 0;
|
|
int j = 0;
|
|
int nSize = 0;
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
CLogDataInfo *pLog = NULL;
|
|
|
|
if (NULL == pArray)
|
|
{
|
|
dwErr = ERROR_INVALID_PARAMETER;
|
|
goto done;
|
|
}
|
|
|
|
nSize = (int) pArray->GetSize();
|
|
|
|
if (0 == nSize)
|
|
goto done;
|
|
|
|
//Merely delete the first element
|
|
|
|
pLog = pArray->GetAt(0);
|
|
delete pLog;
|
|
pArray->RemoveAt(0);
|
|
|
|
done:
|
|
return dwErr;
|
|
}
|
|
|
|
|
|
void
|
|
CSpdInfo::StartFromFirstRecord(
|
|
BOOL bFromFirst)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
CSpdInfo::StartFromFirstRecord:
|
|
Sets the read location to start from the first or from the end of the
|
|
table
|
|
|
|
Arguments:
|
|
|
|
IN bFromFirst - TRUE if the read should be done from the beginning of the
|
|
database, FALSE otherwise
|
|
|
|
Returns:
|
|
|
|
Nothing.
|
|
|
|
--*/
|
|
{
|
|
m_csData.Lock();
|
|
|
|
m_bFromFirst = bFromFirst;
|
|
|
|
m_csData.Unlock();
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CSpdInfo::InternalEnumLogData(
|
|
CLogDataInfoArray *pArray,
|
|
DWORD dwPreferredNum,
|
|
BOOL bFromFirst
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
CSpdInfo::InternalEnumLogData - Enumerates data from the service and adds
|
|
to pArray.
|
|
|
|
Arguments:
|
|
[out] pArray - New values are appended if any
|
|
[in] dwPreferredNum - Holds the number of records requested
|
|
|
|
Returns:
|
|
|
|
HRESULT_FROM_WIN32() of the following codes
|
|
ERROR_SUCCESS on success
|
|
ERROR_NO_MORE_ITEMS on no more items
|
|
ERROR_SERVICE_DISABLED otherwise
|
|
|
|
--*/
|
|
{
|
|
HRESULT hr = hrOK;
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
HANDLE hsession = NULL;
|
|
DWORD dwCrtNum = 0;
|
|
PWZC_DB_RECORD pDbRecord = NULL;
|
|
PWZC_DB_RECORD pWZCRecords = NULL;
|
|
DWORD dwNumRecords = 0;
|
|
CLogDataInfo *pLogDataInfo = NULL;
|
|
int i = 0;
|
|
|
|
ASSERT(pArray);
|
|
|
|
FreeItemsAndEmptyArray(*pArray);
|
|
GetSession(&hsession);
|
|
|
|
while (ERROR_SUCCESS == dwErr)
|
|
{
|
|
dwCrtNum = (DWORD)pArray->GetSize();
|
|
|
|
dwErr = EnumWZCDbLogRecords(hsession,
|
|
NULL,
|
|
&bFromFirst,
|
|
dwPreferredNum,
|
|
&pWZCRecords,
|
|
&dwNumRecords,
|
|
NULL);
|
|
|
|
bFromFirst = FALSE;
|
|
pArray->SetSize(dwCrtNum + dwNumRecords);
|
|
|
|
for (i = 0, pDbRecord = pWZCRecords;
|
|
i < (int)dwNumRecords;
|
|
i++, pDbRecord++)
|
|
{
|
|
pLogDataInfo = new CLogDataInfo;
|
|
if (NULL == pLogDataInfo)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
goto Error;
|
|
}
|
|
*pLogDataInfo = *pDbRecord;
|
|
(*pArray)[dwCrtNum + i] = pLogDataInfo;
|
|
|
|
RpcFree(pDbRecord->message.pData);
|
|
RpcFree(pDbRecord->context.pData);
|
|
RpcFree(pDbRecord->ssid.pData);
|
|
RpcFree(pDbRecord->remotemac.pData);
|
|
RpcFree(pDbRecord->localmac.pData);
|
|
}
|
|
|
|
RpcFree(pWZCRecords);
|
|
}
|
|
|
|
switch (dwErr)
|
|
{
|
|
case ERROR_SUCCESS:
|
|
case ERROR_NO_MORE_ITEMS:
|
|
hr = HRESULT_FROM_WIN32(ERROR_SUCCESS);
|
|
break;
|
|
|
|
default:
|
|
hr = HRESULT_FROM_WIN32(dwErr);
|
|
break;
|
|
}
|
|
|
|
COM_PROTECT_ERROR_LABEL;
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CSpdInfo::EnumLogData(
|
|
PDWORD pdwNew,
|
|
PDWORD pdwTotal)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
CSpdInfo::EnumLogData:
|
|
Enumerates logs differentially
|
|
|
|
Arguments:
|
|
|
|
Returns:
|
|
|
|
--*/
|
|
{
|
|
int i = 0;
|
|
int nStoreSize = 0;
|
|
int nTempStoreSize = 0;
|
|
int nNumToDel = 0;
|
|
HRESULT hr = hrOK;
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
DWORD dwCurrentIndexType = 0;
|
|
DWORD dwCurrentSortOption = 0;
|
|
DWORD dwNumRequest = MAX_NUM_RECORDS;
|
|
DWORD dwOffset = 0;
|
|
DWORD dwStoreSize = 0;
|
|
HANDLE hSession = NULL;
|
|
CLogDataInfo *pLogInfo = NULL;
|
|
CLogDataInfoArray arrayTemp;
|
|
BOOL bFromFirst = FALSE;
|
|
|
|
if (false == m_session_init)
|
|
{
|
|
dwErr = OpenWZCDbLogSession(
|
|
NULL/*(LPTSTR)(LPCTSTR)m_stMachineName*/,
|
|
0,
|
|
&hSession);
|
|
|
|
if (dwErr != ERROR_SUCCESS)
|
|
{
|
|
hr = HRESULT_FROM_WIN32(dwErr);
|
|
goto Error;
|
|
}
|
|
|
|
SetSession(hSession);
|
|
}
|
|
|
|
ASSERT(m_session_init == true);
|
|
|
|
//
|
|
// If our session was created successfully, we should go ahead and pick up
|
|
// data from the database. If not we should return.
|
|
//
|
|
|
|
dwStoreSize = GetLogDataCount();
|
|
|
|
if (dwStoreSize == 0)
|
|
bFromFirst = TRUE;
|
|
|
|
CORg(InternalEnumLogData(&arrayTemp, dwNumRequest, bFromFirst));
|
|
|
|
m_csData.Lock();
|
|
|
|
nTempStoreSize = (int) arrayTemp.GetSize();
|
|
|
|
if (pdwNew != NULL)
|
|
*pdwNew = nTempStoreSize;
|
|
|
|
//
|
|
// Add new items to our cache. If we have read records our earlier, remove
|
|
// the first element from the new array, as the database would return the
|
|
// last record once again.
|
|
//
|
|
|
|
if (nTempStoreSize > 0)
|
|
{
|
|
if (bFromFirst == FALSE)
|
|
EliminateDuplicates(&arrayTemp);
|
|
|
|
m_arrayLogData.Append(arrayTemp);
|
|
}
|
|
|
|
//
|
|
// Delete the old items if we are at the window
|
|
//
|
|
|
|
nStoreSize = (int) m_arrayLogData.GetSize();
|
|
|
|
if (nStoreSize >= m_nNumRecords)
|
|
{
|
|
nNumToDel = nStoreSize - m_nNumRecords;
|
|
|
|
//
|
|
// The oldest elements are at zero
|
|
//
|
|
|
|
for (i=0; i < nNumToDel; i++)
|
|
delete m_arrayLogData.GetAt(i);
|
|
m_arrayLogData.RemoveAt(0, nNumToDel);
|
|
|
|
ASSERT(m_nNumRecords == m_arrayLogData.GetSize());
|
|
nStoreSize = m_nNumRecords;
|
|
}
|
|
|
|
if (pdwTotal != NULL)
|
|
*pdwTotal = nStoreSize;
|
|
|
|
m_IndexMgrLogData.Reset();
|
|
for (i = 0; i < nStoreSize; i++)
|
|
{
|
|
pLogInfo = m_arrayLogData.GetAt(i);
|
|
m_IndexMgrLogData.AddItem(pLogInfo);
|
|
}
|
|
|
|
//
|
|
// Re-sort based on the IndexType and Sort options
|
|
//
|
|
|
|
SortLogData(m_dwSortIndex, m_dwSortOption);
|
|
|
|
m_csData.Unlock();
|
|
|
|
COM_PROTECT_ERROR_LABEL;
|
|
if (FAILED(hr))
|
|
{
|
|
switch (hr)
|
|
{
|
|
case HRESULT_FROM_WIN32(ERROR_REMOTE_SESSION_LIMIT_EXCEEDED):
|
|
//
|
|
// Pop up a message...
|
|
//
|
|
|
|
AfxMessageBox(
|
|
IDS_ERR_SPD_UNAVAILABLE,
|
|
MB_OK | MB_ICONEXCLAMATION,
|
|
0);
|
|
case HRESULT_FROM_WIN32(ERROR_SERVICE_DISABLED):
|
|
//
|
|
// Reset the session if initialised
|
|
//
|
|
|
|
if (m_session_init == true)
|
|
ResetSession();
|
|
|
|
//
|
|
// Flush the logs
|
|
//
|
|
FlushLogs();
|
|
hr = S_OK;
|
|
break;
|
|
|
|
default:
|
|
//
|
|
// Unexpected error, this should never happen.
|
|
//
|
|
|
|
ASSERT(FALSE);
|
|
hr = S_FALSE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
HRESULT
|
|
CSpdInfo::FlushLogs()
|
|
/*++
|
|
CSpdInfo::FlushLogs - Flushes logs in the data base and resets the index
|
|
manager
|
|
--*/
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
FreeItemsAndEmptyArray(m_arrayLogData);
|
|
m_IndexMgrLogData.Reset();
|
|
|
|
return hr;
|
|
}
|
|
|
|
DWORD
|
|
CSpdInfo::GetLogDataCount()
|
|
{
|
|
DWORD dwSize = 0;
|
|
CSingleLock cLock(&m_csData);
|
|
|
|
cLock.Lock();
|
|
|
|
dwSize = (DWORD) m_arrayLogData.GetSize();
|
|
|
|
cLock.Unlock();
|
|
return dwSize;
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CSpdInfo::InternalGetSpecificLog(
|
|
CLogDataInfo *pLogDataInfo
|
|
)
|
|
/*++
|
|
CSpdInfo::InternalGetSpecificLog: Internal function to retrieve all fields
|
|
of requested record
|
|
|
|
Arguments:
|
|
[in/out] pLogDataInfo - On entry has the partial record,
|
|
On exit has the complete record if successful
|
|
|
|
Returns:
|
|
S_OK on Success
|
|
--*/
|
|
{
|
|
HRESULT hr = S_OK;
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
DWORD dwNumRecords = 0;
|
|
WZC_DB_RECORD wzcTemplate;
|
|
PWZC_DB_RECORD pwzcRecordList = NULL;
|
|
|
|
if (false == m_session_init)
|
|
{
|
|
hr = HRESULT_FROM_WIN32(ERROR_INVALID_HANDLE);
|
|
goto Error;
|
|
}
|
|
|
|
memset(&wzcTemplate, 0, sizeof(WZC_DB_RECORD));
|
|
|
|
//Fill up template
|
|
dwErr = pLogDataInfo->ConvertToDbRecord(&wzcTemplate);
|
|
if (dwErr != ERROR_SUCCESS)
|
|
{
|
|
hr = HRESULT_FROM_WIN32(dwErr);
|
|
goto Error;
|
|
}
|
|
|
|
dwErr = GetSpecificLogRecord(m_session,
|
|
&wzcTemplate,
|
|
&pwzcRecordList,
|
|
&dwNumRecords,
|
|
NULL);
|
|
if (dwErr != ERROR_SUCCESS)
|
|
{
|
|
hr = HRESULT_FROM_WIN32(dwErr);
|
|
goto FreeOnError;
|
|
}
|
|
|
|
if (dwNumRecords != 1)
|
|
{
|
|
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
|
|
goto FreeOnError;
|
|
}
|
|
|
|
//Fill up return value
|
|
*pLogDataInfo = pwzcRecordList[0];
|
|
|
|
FreeOnError:
|
|
DeallocateDbRecord(&wzcTemplate);
|
|
|
|
COM_PROTECT_ERROR_LABEL;
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CSpdInfo::GetSpecificLog(
|
|
int iIndex,
|
|
CLogDataInfo *pLogData
|
|
)
|
|
/*++
|
|
CSpdInfo::GetSpecificLog: Gets a specific log from the database with all
|
|
information
|
|
|
|
Arguments:
|
|
[in] iIndex - Index to the record to obtain
|
|
[out] pLogData - Storage for the specific record, contains the complete
|
|
record on success
|
|
|
|
Returns:
|
|
S_OK on success
|
|
--*/
|
|
{
|
|
HRESULT hr = S_OK;
|
|
int nSize = 0;
|
|
CLogDataInfo *pLogDataInfo = NULL;
|
|
|
|
m_csData.Lock();
|
|
|
|
nSize = (DWORD)m_arrayLogData.GetSize();
|
|
if ((iIndex < 0) || (iIndex >= nSize))
|
|
{
|
|
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
|
|
goto Error;
|
|
}
|
|
|
|
pLogDataInfo = (CLogDataInfo*)m_IndexMgrLogData.GetItemData(iIndex);
|
|
|
|
if (NULL == pLogDataInfo)
|
|
{
|
|
hr = HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER);
|
|
goto Error;
|
|
}
|
|
|
|
//Get the complete record
|
|
*pLogData = *pLogDataInfo;
|
|
CORg(InternalGetSpecificLog(pLogData));
|
|
|
|
COM_PROTECT_ERROR_LABEL;
|
|
m_csData.Unlock();
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT
|
|
CSpdInfo::GetLogDataInfo(
|
|
int iIndex,
|
|
CLogDataInfo * pLogData
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
int nSize = 0;
|
|
CLogDataInfo *pLogDataInfo = NULL;
|
|
|
|
m_csData.Lock();
|
|
|
|
nSize = (DWORD)m_arrayLogData.GetSize();
|
|
if ((iIndex < 0) || (iIndex >= nSize))
|
|
{
|
|
hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
|
|
goto Error;
|
|
}
|
|
|
|
pLogDataInfo = (CLogDataInfo*)m_IndexMgrLogData.GetItemData(iIndex);
|
|
|
|
if (NULL == pLogDataInfo)
|
|
{
|
|
hr = HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER);
|
|
goto Error;
|
|
}
|
|
|
|
//Get the partial record
|
|
*pLogData = *pLogDataInfo;
|
|
|
|
COM_PROTECT_ERROR_LABEL;
|
|
m_csData.Unlock();
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CSpdInfo::SortLogData(
|
|
DWORD dwIndexType,
|
|
DWORD dwSortOptions
|
|
)
|
|
{
|
|
return m_IndexMgrLogData.SortLogData(dwIndexType, dwSortOptions);
|
|
}
|
|
|
|
|
|
HRESULT CSpdInfo::SortLogData()
|
|
/*++
|
|
CSpdInfo::SortLogData
|
|
Description: For use externally, locks and sorts with last set sort
|
|
options
|
|
|
|
Parameters:
|
|
|
|
Returns:
|
|
--*/
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
m_csData.Lock();
|
|
|
|
hr = SortLogData(m_dwSortIndex, m_dwSortOption);
|
|
|
|
m_csData.Unlock();
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CSpdInfo::SetSortOptions(
|
|
DWORD dwColID,
|
|
BOOL bAscending
|
|
)
|
|
/*++
|
|
CSpdInfo::SetSortOptions
|
|
Sets the sort options to be used whenever data is enumerated
|
|
|
|
--*/
|
|
{
|
|
HRESULT hr = S_OK;
|
|
DWORD dwSortOption = SORT_ASCENDING;
|
|
|
|
if( (IDS_COL_LOGDATA_TIME != dwColID) &&
|
|
(IDS_COL_LOGDATA_COMP_ID != dwColID) &&
|
|
(IDS_COL_LOGDATA_CAT != dwColID) &&
|
|
(IDS_COL_LOGDATA_LOCAL_MAC_ADDR != dwColID) &&
|
|
(IDS_COL_LOGDATA_REMOTE_MAC_ADDR != dwColID) &&
|
|
(IDS_COL_LOGDATA_SSID != dwColID) &&
|
|
(IDS_COL_LOGDATA_MSG != dwColID) )
|
|
{
|
|
hr = HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER);
|
|
goto done;
|
|
}
|
|
|
|
if (FALSE == bAscending)
|
|
dwSortOption = SORT_DESCENDING;
|
|
|
|
//lock csData so that EnumLogRecords sorts correctly on the next sort
|
|
m_csData.Lock();
|
|
|
|
m_dwSortIndex = dwColID;
|
|
m_dwSortOption = dwSortOption;
|
|
|
|
m_csData.Unlock();
|
|
|
|
done:
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CSpdInfo::FindIndex(
|
|
int *pnIndex,
|
|
CLogDataInfo *pLogDataInfo
|
|
)
|
|
/*++
|
|
CSpdInfo::FindIndex
|
|
Finds the virtual index of the item corresponding to the input LogDataInfo
|
|
|
|
Parameters:
|
|
[out] pnIndex - A pointer to place the result index
|
|
[in] pLogDataInfo - A pointer to the LogDataInfo to be found
|
|
|
|
Returns:
|
|
S_OK on success
|
|
*pnIndex will contain a valid index if found, else will have -1
|
|
|
|
--*/
|
|
{
|
|
int nSize = 0;
|
|
int i = 0;
|
|
HRESULT hr = S_OK;
|
|
BOOL bFound = FALSE;
|
|
CLogDataInfo *pLogDataLHS = NULL;
|
|
|
|
if ( (NULL == pnIndex) || (NULL == pLogDataInfo) )
|
|
{
|
|
hr = HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER);
|
|
goto Error;
|
|
}
|
|
|
|
*pnIndex = -1;
|
|
|
|
m_csData.Lock();
|
|
|
|
nSize = (int) m_arrayLogData.GetSize();
|
|
while ( (i < nSize) && (FALSE == bFound) )
|
|
{
|
|
pLogDataLHS = (CLogDataInfo*) m_IndexMgrLogData.GetItemData(i);
|
|
if (*pLogDataLHS == *pLogDataInfo)
|
|
{
|
|
*pnIndex = i;
|
|
bFound = TRUE;
|
|
}
|
|
else
|
|
i++;
|
|
}
|
|
|
|
m_csData.Unlock();
|
|
|
|
COM_PROTECT_ERROR_LABEL;
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CSpdInfo::GetLastIndex(
|
|
int *pnIndex
|
|
)
|
|
/*++
|
|
CSpdInfo::GetLastIndex
|
|
Returns the virtual index for the last item in the list
|
|
|
|
Returns:
|
|
S_OK on success
|
|
--*/
|
|
{
|
|
int nLastIndex = 0;
|
|
HRESULT hr = S_OK;
|
|
|
|
if (NULL == pnIndex)
|
|
{
|
|
hr = HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER);
|
|
goto Error;
|
|
}
|
|
|
|
m_csData.Lock();
|
|
|
|
nLastIndex = (int) m_arrayLogData.GetSize();
|
|
nLastIndex--;
|
|
*pnIndex = nLastIndex;
|
|
|
|
m_csData.Unlock();
|
|
|
|
COM_PROTECT_ERROR_LABEL;
|
|
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.
|
|
|
|
HANDLE hSession;
|
|
|
|
GetSession(&hSession);
|
|
|
|
if (m_session_init == true)
|
|
{
|
|
CloseWZCDbLogSession(hSession);
|
|
m_session_init = false;
|
|
m_bFromFirst = TRUE;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
|
|
DWORD
|
|
DeallocateDbRecord(
|
|
PWZC_DB_RECORD const pwzcRec
|
|
)
|
|
/*++
|
|
DeallocateDbRecord - Frees up the internal memory used in a WZC_DB_RECORD
|
|
structure. To be used only when space has been allocated by sources other
|
|
than RPC. Does not deallocate outer level
|
|
|
|
Arguments:
|
|
[in/out]pwzcRec - Holds the record to free. Internal mem alone is freed and
|
|
contents freed are annulled.
|
|
|
|
Returns:
|
|
ERROR_SUCCESS on success
|
|
--*/
|
|
{
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
|
|
if (NULL != pwzcRec->message.pData)
|
|
{
|
|
delete [] pwzcRec->message.pData;
|
|
pwzcRec->message.pData = NULL;
|
|
}
|
|
|
|
if (NULL != pwzcRec->localmac.pData)
|
|
{
|
|
delete [] pwzcRec->localmac.pData;
|
|
pwzcRec->localmac.pData = NULL;
|
|
}
|
|
|
|
if (NULL != pwzcRec->remotemac.pData)
|
|
{
|
|
delete [] pwzcRec->remotemac.pData;
|
|
pwzcRec->remotemac.pData = NULL;
|
|
}
|
|
|
|
if (NULL != pwzcRec->ssid.pData)
|
|
{
|
|
delete [] pwzcRec->ssid.pData;
|
|
pwzcRec->ssid.pData = NULL;
|
|
}
|
|
|
|
if (NULL != pwzcRec->context.pData)
|
|
{
|
|
delete [] pwzcRec->context.pData;
|
|
pwzcRec->ssid.pData = NULL;
|
|
}
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
|
|
//
|
|
// 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);
|
|
}
|
|
|
|
|