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.
552 lines
10 KiB
552 lines
10 KiB
// SSRMemberShip.cpp : Implementation of CSsrMembership
|
|
|
|
#include "stdafx.h"
|
|
#include "global.h"
|
|
|
|
#include "SSRTE.h"
|
|
#include "SSRMemberShip.h"
|
|
|
|
#include "SSRLog.h"
|
|
|
|
#include "MemberAccess.h"
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CSsrMembership
|
|
|
|
|
|
|
|
|
|
/*
|
|
Routine Description:
|
|
|
|
Name:
|
|
|
|
CSsrMembership::CSsrMembership
|
|
|
|
Functionality:
|
|
|
|
constructor. This constructor also builds the member list.
|
|
|
|
Virtual:
|
|
|
|
no.
|
|
|
|
Arguments:
|
|
|
|
none.
|
|
|
|
Return Value:
|
|
|
|
none.
|
|
|
|
Notes:
|
|
|
|
|
|
*/
|
|
|
|
CSsrMembership::CSsrMembership()
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
Routine Description:
|
|
|
|
Name:
|
|
|
|
CSsrMembership::~CSsrMembership
|
|
|
|
Functionality:
|
|
|
|
destructor
|
|
|
|
Virtual:
|
|
|
|
yes.
|
|
|
|
Arguments:
|
|
|
|
none.
|
|
|
|
Return Value:
|
|
|
|
none.
|
|
|
|
Notes:
|
|
|
|
|
|
*/
|
|
|
|
CSsrMembership::~CSsrMembership()
|
|
{
|
|
map<const BSTR, CSsrMemberAccess*, strLessThan<BSTR> >::iterator it = m_ssrMemberAccessMap.begin();
|
|
map<const BSTR, CSsrMemberAccess*, strLessThan<BSTR> >::iterator itEnd = m_ssrMemberAccessMap.end();
|
|
|
|
while(it != itEnd)
|
|
{
|
|
CSsrMemberAccess * pMA = (*it).second;
|
|
pMA->Release();
|
|
it++;
|
|
}
|
|
|
|
m_ssrMemberAccessMap.clear();
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CSsrMembership::LoadAllMember ()
|
|
/*++
|
|
Routine Description:
|
|
|
|
Name:
|
|
|
|
CSsrMembership::LoadAllMember
|
|
|
|
Functionality:
|
|
|
|
Will try to load all information about all the members that
|
|
are registered with SSR.
|
|
|
|
Virtual:
|
|
|
|
no.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
Success: various success code.
|
|
|
|
Failure: various error codes. However, we may tolerate that and only
|
|
load those that we can load successfully. So, don't blindly quit.
|
|
|
|
Notes:
|
|
|
|
|
|
--*/
|
|
{
|
|
//
|
|
// We should never load more than once.
|
|
//
|
|
|
|
if (m_ssrMemberAccessMap.size() > 0)
|
|
{
|
|
return S_OK; // we let you call it if you have already call it before
|
|
}
|
|
|
|
//
|
|
// Let's enumerate through the Members directory's .xml files. They will
|
|
// all be considered as member registration files.
|
|
//
|
|
|
|
WCHAR wcsXmlFiles[MAX_PATH + 2];
|
|
_snwprintf(wcsXmlFiles, MAX_PATH + 1, L"%s\\Members\\*.xml", g_wszSsrRoot);
|
|
|
|
wcsXmlFiles[MAX_PATH + 1] = L'\0';
|
|
|
|
long lDirLen = wcslen(wcsXmlFiles);
|
|
|
|
if (lDirLen > MAX_PATH)
|
|
{
|
|
return HRESULT_FROM_WIN32(ERROR_FILENAME_EXCED_RANGE);
|
|
}
|
|
|
|
lDirLen -= 5;
|
|
|
|
WIN32_FIND_DATA wfd;
|
|
DWORD dwErr;
|
|
HRESULT hr;
|
|
|
|
|
|
HANDLE hFindFiles = FindFirstFile(
|
|
wcsXmlFiles, // file name
|
|
&wfd // information buffer
|
|
);
|
|
|
|
if (INVALID_HANDLE_VALUE == hFindFiles)
|
|
{
|
|
hr = S_FALSE;
|
|
g_fblog.LogError(hr,
|
|
L"There is no member to load",
|
|
wcsXmlFiles
|
|
);
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT hrFirstError = S_OK;
|
|
long lFileNameLength;
|
|
|
|
while (INVALID_HANDLE_VALUE != hFindFiles)
|
|
{
|
|
//
|
|
// make sure that we won't load anything other then a perfect .xml extension
|
|
// file. I found that this Find will return such files: adc.xml-xxx
|
|
//
|
|
|
|
lFileNameLength = wcslen(wfd.cFileName);
|
|
|
|
if (_wcsicmp(wfd.cFileName + lFileNameLength - 4, L".xml") == 0)
|
|
{
|
|
//
|
|
// Get the file name and then load that member
|
|
//
|
|
|
|
wcsncpy(wcsXmlFiles + lDirLen, wfd.cFileName, lFileNameLength + 1);
|
|
|
|
hr = LoadMember(wcsXmlFiles);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
g_fblog.LogError(hr,
|
|
L"CSsrMembership loading member failed",
|
|
wcsXmlFiles
|
|
);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hrFirstError = hr;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!FindNextFile (hFindFiles, &wfd))
|
|
{
|
|
dwErr = GetLastError();
|
|
if (ERROR_NO_MORE_FILES != dwErr)
|
|
{
|
|
//
|
|
// log it
|
|
//
|
|
|
|
g_fblog.LogError(HRESULT_FROM_WIN32(dwErr),
|
|
L"CSsrMembership",
|
|
L"FindNextFile"
|
|
);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
FindClose(hFindFiles);
|
|
|
|
return hrFirstError;
|
|
}
|
|
|
|
|
|
/*
|
|
Routine Description:
|
|
|
|
Name:
|
|
|
|
CSsrMembership::LoadMember
|
|
|
|
Functionality:
|
|
|
|
By given a valid member name, this function will load all the
|
|
detailed information from the registry.
|
|
|
|
Virtual:
|
|
|
|
no.
|
|
|
|
Arguments:
|
|
|
|
|
|
wszMemberFilePath - The XML registration file path for a particular member.
|
|
|
|
Return Value:
|
|
|
|
Success: S_OK.
|
|
|
|
Failure: various error codes
|
|
|
|
Notes:
|
|
|
|
|
|
*/
|
|
|
|
HRESULT
|
|
CSsrMembership::LoadMember (
|
|
IN LPCWSTR wszMemberFilePath
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
CComObject<CSsrMemberAccess> * pMA = NULL;
|
|
|
|
hr = CComObject<CSsrMemberAccess>::CreateInstance(&pMA);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
//
|
|
// holding on to the object. When the member access
|
|
// map cleans up, remember to let go the objects
|
|
//
|
|
|
|
pMA->AddRef();
|
|
|
|
hr = pMA->Load(wszMemberFilePath);
|
|
|
|
if (S_OK == hr)
|
|
{
|
|
//
|
|
// Everything is fine and we loaded the member.
|
|
// Add it to our map. The map owns the object from this point on.
|
|
//
|
|
|
|
m_ssrMemberAccessMap.insert(
|
|
map<const BSTR, CSsrMemberAccess*, strLessThan<BSTR> >::value_type(pMA->GetName(),
|
|
pMA)
|
|
);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// let go the object
|
|
//
|
|
|
|
pMA->Release();
|
|
|
|
g_fblog.LogError(hr, wszMemberFilePath, NULL);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
g_fblog.LogError(hr, wszMemberFilePath, NULL);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
Routine Description:
|
|
|
|
Name:
|
|
|
|
CSsrMembership::GetAllMembers
|
|
|
|
Functionality:
|
|
|
|
Retrieve all members currently registered on the system.
|
|
|
|
Virtual:
|
|
|
|
yes.
|
|
|
|
Arguments:
|
|
|
|
pvarArrayMembers - Receives names of the members
|
|
|
|
Return Value:
|
|
|
|
?.
|
|
|
|
Notes:
|
|
|
|
*/
|
|
|
|
STDMETHODIMP CSsrMembership::GetAllMembers (
|
|
OUT VARIANT * pvarArrayMembers // [out, retval]
|
|
)
|
|
{
|
|
if (pvarArrayMembers == NULL)
|
|
{
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
//
|
|
// have a clean output parameter, no matter what
|
|
//
|
|
|
|
::VariantInit(pvarArrayMembers);
|
|
|
|
//
|
|
// prepare the safearray
|
|
//
|
|
|
|
SAFEARRAYBOUND rgsabound[1];
|
|
rgsabound[0].lLbound = 0;
|
|
rgsabound[0].cElements = m_ssrMemberAccessMap.size();
|
|
|
|
SAFEARRAY * psa = ::SafeArrayCreate(VT_VARIANT , 1, rgsabound);
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
if (psa == NULL)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
else
|
|
{
|
|
map<const BSTR, CSsrMemberAccess*, strLessThan<BSTR> >::iterator it = m_ssrMemberAccessMap.begin();
|
|
map<const BSTR, CSsrMemberAccess*, strLessThan<BSTR> >::iterator itEnd = m_ssrMemberAccessMap.end();
|
|
|
|
//
|
|
// we only add one name at a time
|
|
//
|
|
|
|
long indecies[1] = {0};
|
|
|
|
while(it != itEnd)
|
|
{
|
|
CSsrMemberAccess * pMA = (*it).second;
|
|
|
|
VARIANT varName;
|
|
varName.vt = VT_BSTR;
|
|
|
|
//
|
|
// don't clean up varName! CSsrMemberAccess::GetName returns
|
|
// a const BSTR which simplies points to the cached variable!
|
|
//
|
|
|
|
varName.bstrVal = pMA->GetName();
|
|
|
|
hr = ::SafeArrayPutElement(psa, indecies, &varName);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
break;
|
|
}
|
|
|
|
indecies[0]++;
|
|
|
|
++it;
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
pvarArrayMembers->vt = VT_ARRAY | VT_VARIANT;
|
|
pvarArrayMembers->parray = psa;
|
|
}
|
|
else
|
|
{
|
|
::SafeArrayDestroy(psa);
|
|
}
|
|
|
|
}
|
|
|
|
return hr;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
Routine Description:
|
|
|
|
Name:
|
|
|
|
CSsrMembership::GetMember
|
|
|
|
Functionality:
|
|
|
|
Retrieve one member of the given name.
|
|
|
|
Virtual:
|
|
|
|
yes.
|
|
|
|
Arguments:
|
|
|
|
pvarMember - Receives ISsrMemberAccess object of the named member.
|
|
|
|
Return Value:
|
|
|
|
Success: S_OK;
|
|
|
|
Failure: various error codes.
|
|
|
|
Notes:
|
|
|
|
|
|
*/
|
|
|
|
STDMETHODIMP CSsrMembership::GetMember (
|
|
IN BSTR bstrMemberName,
|
|
OUT VARIANT * pvarMember //[out, retval]
|
|
)
|
|
{
|
|
if (bstrMemberName == NULL || *bstrMemberName == L'\0' || pvarMember == NULL)
|
|
{
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
::VariantInit(pvarMember);
|
|
|
|
CSsrMemberAccess * pMA = GetMemberByName(bstrMemberName);
|
|
HRESULT hr = S_OK;
|
|
|
|
if (pMA != NULL)
|
|
{
|
|
pvarMember->vt = VT_DISPATCH;
|
|
hr = pMA->QueryInterface(IID_ISsrMemberAccess,
|
|
(LPVOID*)&(pvarMember->pdispVal) );
|
|
if (hr != S_OK)
|
|
{
|
|
pvarMember->vt = VT_EMPTY;
|
|
hr = E_SSR_MEMBER_NOT_FOUND;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = E_SSR_MEMBER_NOT_FOUND;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
Routine Description:
|
|
|
|
Name:
|
|
|
|
CSsrMembership::GetMemberByName
|
|
|
|
Functionality:
|
|
|
|
Will find the CSsrMemberAccess object based the name.
|
|
|
|
Virtual:
|
|
|
|
No.
|
|
|
|
Arguments:
|
|
|
|
bstrMemberName - The member's name
|
|
|
|
Return Value:
|
|
|
|
None NULL if the object is found. Otherwise, it returns NULL.
|
|
|
|
Notes:
|
|
|
|
Since this is a helper function, we don't call AddRef to the returned object!
|
|
|
|
*/
|
|
|
|
CSsrMemberAccess*
|
|
CSsrMembership::GetMemberByName (
|
|
IN BSTR bstrMemberName
|
|
)
|
|
{
|
|
map<const BSTR, CSsrMemberAccess*, strLessThan<BSTR> >::iterator it = m_ssrMemberAccessMap.find(bstrMemberName);
|
|
|
|
if (it != m_ssrMemberAccessMap.end())
|
|
{
|
|
CSsrMemberAccess * pMA = (*it).second;
|
|
return pMA;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
|