1023 lines
22 KiB
C++
1023 lines
22 KiB
C++
/* ----------------------------------------------------------------------
|
|
|
|
Module: ULS.DLL (Service Provider)
|
|
File: splmtg.cpp
|
|
Content: This file contains the local meeting object.
|
|
History:
|
|
10/15/96 Chu, Lon-Chan [lonchanc]
|
|
Created.
|
|
|
|
Copyright (c) Microsoft Corporation 1996-1997
|
|
|
|
---------------------------------------------------------------------- */
|
|
|
|
#include "ulsp.h"
|
|
#include "spinc.h"
|
|
|
|
#ifdef ENABLE_MEETING_PLACE
|
|
|
|
// Array of constant strings for user object's attribute names
|
|
//
|
|
const TCHAR *c_apszMtgStdAttrNames[COUNT_ENUM_MTGATTR] =
|
|
{
|
|
TEXT ("CN"), // Meeting ID
|
|
TEXT ("ConfType"), // Meeting Type
|
|
TEXT ("ConfMemberType"), // Attendee Type
|
|
TEXT ("ConfDesc"), // Description
|
|
TEXT ("ConfHostName"), // Host Name
|
|
TEXT ("ConfHostAddress"), // IP Address
|
|
|
|
TEXT ("ConfMemberList"), // Members
|
|
TEXT ("ssecurity"),
|
|
TEXT ("sttl"),
|
|
|
|
TEXT ("objectClass"),
|
|
TEXT ("o"),
|
|
TEXT ("c"),
|
|
};
|
|
|
|
|
|
const TCHAR c_szMtgDefC[] = TEXT ("us");
|
|
|
|
|
|
/* ---------- public methods ----------- */
|
|
|
|
|
|
SP_CMeeting::
|
|
SP_CMeeting ( DWORD dwContext )
|
|
:
|
|
m_cRefs (0), // Reference count
|
|
m_uSignature (MTGOBJ_SIGNATURE), // Mtg object's signature
|
|
m_pszMtgName (NULL), // Clean the meeting name
|
|
m_pszDN (NULL), // Clean DN
|
|
m_pszRefreshFilter (NULL), // Clean up the refresh search filter
|
|
m_dwIPAddress (0), // Clean local IP address
|
|
m_uTTL (ILS_DEF_REFRESH_MINUTE) // Reset time to live value (min)
|
|
{
|
|
m_dwContext = dwContext;
|
|
|
|
// Clean up attached server info structure
|
|
//
|
|
::ZeroMemory (&m_ServerInfo, sizeof (m_ServerInfo));
|
|
|
|
// Clean up the scratch buffer for caching pointers to attribute values
|
|
//
|
|
::ZeroMemory (&m_MtgInfo, sizeof (m_MtgInfo));
|
|
|
|
// Indicate this user is not registered yet
|
|
//
|
|
SetRegNone ();
|
|
}
|
|
|
|
|
|
SP_CMeeting::
|
|
~SP_CMeeting ( VOID )
|
|
{
|
|
// Invalidate the user object's signature
|
|
//
|
|
m_uSignature = (ULONG) -1;
|
|
|
|
// Free server info structure
|
|
//
|
|
::IlsFreeServerInfo (&m_ServerInfo);
|
|
|
|
// Free meeting name
|
|
//
|
|
MemFree (m_pszMtgName);
|
|
|
|
// Free DN
|
|
//
|
|
MemFree (m_pszDN);
|
|
|
|
// Free the refresh search filter
|
|
//
|
|
MemFree (m_pszRefreshFilter);
|
|
|
|
// Release the previous prefix for extended attribute names
|
|
//
|
|
::IlsReleaseAnyAttrsPrefix (&(m_MtgInfo.AnyAttrs));
|
|
}
|
|
|
|
|
|
ULONG
|
|
SP_CMeeting::
|
|
AddRef ( VOID )
|
|
{
|
|
::InterlockedIncrement (&m_cRefs);
|
|
return m_cRefs;
|
|
}
|
|
|
|
|
|
ULONG
|
|
SP_CMeeting::
|
|
Release ( VOID )
|
|
{
|
|
MyAssert (m_cRefs != 0);
|
|
::InterlockedDecrement (&m_cRefs);
|
|
|
|
ULONG cRefs = m_cRefs;
|
|
if (cRefs == 0)
|
|
delete this;
|
|
|
|
return cRefs;
|
|
}
|
|
|
|
|
|
HRESULT SP_CMeeting::
|
|
Register (
|
|
ULONG uRespID,
|
|
SERVER_INFO *pServerInfo,
|
|
LDAP_MEETINFO *pInfo )
|
|
{
|
|
MyAssert (pInfo != NULL);
|
|
MyAssert (MyIsGoodString (pServerInfo->pszServerName));
|
|
|
|
// Cache the server info
|
|
//
|
|
HRESULT hr = ::IlsCopyServerInfo (&m_ServerInfo, pServerInfo);
|
|
if (hr != S_OK)
|
|
return hr;
|
|
|
|
// Cache the meeting info
|
|
// lonchanc: CacheInfo() is not a method in the meeting object
|
|
// because we pass in meeting name in SetMeetingInfo()
|
|
// rather than meeting object handle.
|
|
//
|
|
hr = ::MtgCacheInfo (pInfo, &m_MtgInfo);
|
|
if (hr != S_OK)
|
|
return hr;
|
|
|
|
// If the application sets an IP address,
|
|
// then we will use what the app provides,
|
|
// otherwise, we will get the IP address via winsock.
|
|
//
|
|
if (pInfo->uOffsetHostIPAddress == INVALID_OFFSET)
|
|
{
|
|
// Get local IP address
|
|
//
|
|
m_dwIPAddress = 0;
|
|
hr = ::GetLocalIPAddress (&m_dwIPAddress);
|
|
if (hr != S_OK)
|
|
return hr;
|
|
|
|
// Create IP address string
|
|
//
|
|
m_MtgInfo.apszStdAttrValues[ENUM_MTGATTR_IP_ADDRESS] = &m_MtgInfo.szIPAddress[0];
|
|
::GetLongString (m_dwIPAddress, &m_MtgInfo.szIPAddress[0]);
|
|
}
|
|
|
|
// Create client signature string
|
|
//
|
|
m_MtgInfo.apszStdAttrValues[ENUM_MTGATTR_CLIENT_SIG] = &m_MtgInfo.szClientSig[0];
|
|
::GetLongString (g_dwClientSig, &m_MtgInfo.szClientSig[0]);
|
|
|
|
// Create TTL string
|
|
//
|
|
m_MtgInfo.apszStdAttrValues[ENUM_MTGATTR_TTL] = &m_MtgInfo.szTTL[0];
|
|
::GetLongString (m_uTTL, &m_MtgInfo.szTTL[0]);
|
|
|
|
// Ideally, o= and c= should be read in from registiry
|
|
// but for now, we simply hard code it
|
|
//
|
|
m_MtgInfo.apszStdAttrValues[ENUM_MTGATTR_OBJECT_CLASS] = (TCHAR *) &c_szRTConf[0];
|
|
m_MtgInfo.apszStdAttrValues[ENUM_MTGATTR_O] = (TCHAR *) &c_szDefO[0];
|
|
m_MtgInfo.apszStdAttrValues[ENUM_MTGATTR_C] = (TCHAR *) &c_szMtgDefC[0];
|
|
|
|
// Duplicate the mtg name
|
|
//
|
|
m_pszMtgName = My_strdup (m_MtgInfo.apszStdAttrValues[ENUM_MTGATTR_CN]);
|
|
if (m_pszMtgName == NULL)
|
|
return ILS_E_MEMORY;
|
|
|
|
// Build DN
|
|
//
|
|
m_pszDN = ::IlsBuildDN (m_ServerInfo.pszBaseDN,
|
|
m_MtgInfo.apszStdAttrValues[ENUM_MTGATTR_C],
|
|
m_MtgInfo.apszStdAttrValues[ENUM_MTGATTR_O],
|
|
m_MtgInfo.apszStdAttrValues[ENUM_MTGATTR_CN],
|
|
m_MtgInfo.apszStdAttrValues[ENUM_MTGATTR_OBJECT_CLASS]);
|
|
if (m_pszDN == NULL)
|
|
return ILS_E_MEMORY;
|
|
|
|
// Build refreh filter
|
|
//
|
|
m_pszRefreshFilter = ::MtgCreateRefreshFilter (m_pszMtgName);
|
|
if (m_pszRefreshFilter == NULL)
|
|
return ILS_E_MEMORY;
|
|
|
|
// Build modify array for ldap_add()
|
|
//
|
|
LDAPMod **ppMod = NULL;
|
|
hr = CreateRegModArr (&ppMod);
|
|
if (hr != S_OK)
|
|
return hr;
|
|
MyAssert (ppMod != NULL);
|
|
|
|
// so far, we are done with local preparation
|
|
//
|
|
|
|
// Get the connection object
|
|
//
|
|
SP_CSession *pSession = NULL;
|
|
LDAP *ld;
|
|
ULONG uMsgID = (ULONG) -1;
|
|
hr = g_pSessionContainer->GetSession (&pSession, &m_ServerInfo);
|
|
if (hr == S_OK)
|
|
{
|
|
MyAssert (pSession != NULL);
|
|
|
|
// Get the ldap session
|
|
//
|
|
ld = pSession->GetLd ();
|
|
MyAssert (ld != NULL);
|
|
|
|
// Send the data over the wire
|
|
//
|
|
uMsgID = ldap_add (ld, m_pszDN, ppMod);
|
|
if (uMsgID == -1)
|
|
{
|
|
hr = ::LdapError2Hresult (ld->ld_errno);
|
|
}
|
|
|
|
}
|
|
|
|
// Free modify array
|
|
//
|
|
MemFree (ppMod);
|
|
|
|
// Report failure if so
|
|
//
|
|
if (hr != S_OK)
|
|
goto MyExit;
|
|
|
|
// Construct a pending info
|
|
//
|
|
RESP_INFO ri;
|
|
::FillDefRespInfo (&ri, uRespID, ld, uMsgID, INVALID_MSG_ID);
|
|
ri.uNotifyMsg = WM_ILS_REGISTER_MEETING;
|
|
ri.hObject = (HANDLE) this;
|
|
|
|
// Remember the pending result
|
|
//
|
|
hr = g_pRespQueue->EnterRequest (pSession, &ri);
|
|
if (hr != S_OK)
|
|
{
|
|
MyAssert (FALSE);
|
|
goto MyExit;
|
|
}
|
|
|
|
MyExit:
|
|
|
|
if (hr != S_OK)
|
|
{
|
|
if (uMsgID != (ULONG) -1)
|
|
::ldap_abandon (ld, uMsgID);
|
|
|
|
if (pSession != NULL)
|
|
pSession->Disconnect ();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT SP_CMeeting::
|
|
UnRegister ( ULONG uRespID )
|
|
{
|
|
MyAssert (MyIsGoodString (m_pszDN));
|
|
|
|
// Make sure that there is not refresh scheduled for this object
|
|
//
|
|
if (g_pRefreshScheduler != NULL)
|
|
{
|
|
g_pRefreshScheduler->RemoveMtgObject (this);
|
|
}
|
|
else
|
|
{
|
|
MyAssert (FALSE);
|
|
}
|
|
|
|
// If it is not registered on the server,
|
|
// the simply report success
|
|
//
|
|
if (! IsRegRemotely ())
|
|
{
|
|
SetRegNone ();
|
|
::PostMessage (g_hWndNotify, WM_ILS_UNREGISTER_MEETING, uRespID, S_OK);
|
|
return S_OK;
|
|
}
|
|
|
|
// Indicate that we are not registered at all
|
|
//
|
|
SetRegNone ();
|
|
|
|
// Get the session object
|
|
//
|
|
SP_CSession *pSession = NULL;
|
|
LDAP *ld;
|
|
ULONG uMsgID = (ULONG) -1;
|
|
HRESULT hr = g_pSessionContainer->GetSession (&pSession, &m_ServerInfo);
|
|
if (hr == S_OK)
|
|
{
|
|
// Get the ldap session
|
|
//
|
|
MyAssert (pSession != NULL);
|
|
ld = pSession->GetLd ();
|
|
MyAssert (ld != NULL);
|
|
|
|
// Send the data over the wire
|
|
//
|
|
MyAssert (MyIsGoodString (m_pszDN));
|
|
uMsgID = ::ldap_delete (ld, m_pszDN);
|
|
if (uMsgID == -1)
|
|
{
|
|
hr = ::LdapError2Hresult (ld->ld_errno);
|
|
}
|
|
}
|
|
|
|
// Report failure if so
|
|
//
|
|
if (hr != S_OK)
|
|
goto MyExit;
|
|
|
|
// Construct a pending info
|
|
//
|
|
RESP_INFO ri;
|
|
::FillDefRespInfo (&ri, uRespID, ld, uMsgID, INVALID_MSG_ID);
|
|
ri.uNotifyMsg = WM_ILS_UNREGISTER_MEETING;
|
|
|
|
// Remember the pending request
|
|
//
|
|
hr = g_pRespQueue->EnterRequest (pSession, &ri);
|
|
if (hr != S_OK)
|
|
{
|
|
MyAssert (FALSE);
|
|
goto MyExit;
|
|
}
|
|
|
|
MyExit:
|
|
|
|
if (hr != S_OK)
|
|
{
|
|
if (uMsgID != (ULONG) -1)
|
|
::ldap_abandon (ld, uMsgID);
|
|
|
|
if (pSession != NULL)
|
|
pSession->Disconnect ();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT SP_CMeeting::
|
|
UpdateIPAddress ( VOID )
|
|
{
|
|
MyAssert (MyIsGoodString (m_pszDN));
|
|
|
|
// Update cached ip address
|
|
//
|
|
HRESULT hr = ::GetLocalIPAddress (&m_dwIPAddress);
|
|
if (hr != S_OK)
|
|
return hr;
|
|
|
|
// Update the ip address string
|
|
//
|
|
::GetLongString (m_dwIPAddress, &m_MtgInfo.szIPAddress[0]);
|
|
|
|
// Update IP address in the server
|
|
//
|
|
return ::IlsUpdateIPAddress ( &m_ServerInfo,
|
|
m_pszDN,
|
|
STR_MTG_IP_ADDR,
|
|
&m_MtgInfo.szIPAddress[0],
|
|
ISBU_MODOP_MODIFY_USER,
|
|
MtgGetPrefixCount (),
|
|
MtgGetPrefixString ());
|
|
}
|
|
|
|
|
|
/* ---------- protected methods ----------- */
|
|
|
|
|
|
HRESULT SP_CMeeting::
|
|
SendRefreshMsg ( VOID )
|
|
{
|
|
MyAssert (m_pszRefreshFilter != NULL);
|
|
|
|
// Get local IP address
|
|
//
|
|
DWORD dwIPAddress = 0;
|
|
HRESULT hr = ::GetLocalIPAddress (&dwIPAddress);
|
|
if (hr != S_OK)
|
|
{
|
|
MyDebugMsg ((ZONE_KA, "KA(Mtg): cannot get my ip address\r\n"));
|
|
|
|
// Indicate that I am not connected to the server anymore
|
|
//
|
|
SetRegLocally ();
|
|
|
|
// Second, notify this app of the network being down
|
|
//
|
|
::PostMessage (g_hWndNotify, WM_ILS_MEETING_NETWORK_DOWN,
|
|
(WPARAM) this, (LPARAM) m_dwContext);
|
|
|
|
// Report error
|
|
//
|
|
return ILS_E_NETWORK_DOWN;
|
|
}
|
|
|
|
// If dwIPAddress is 0, then we are not on the network any more
|
|
// start relogon process
|
|
//
|
|
if (dwIPAddress == 0)
|
|
{
|
|
MyDebugMsg ((ZONE_KA, "KA(Mtg): ip-addr=0, network down.\r\n"));
|
|
|
|
// Indicate that I am not connected to the server anymore
|
|
//
|
|
SetRegLocally ();
|
|
|
|
// Second, notify this app of the network being down
|
|
//
|
|
::PostMessage (g_hWndNotify, WM_ILS_MEETING_NETWORK_DOWN,
|
|
(WPARAM) this, (LPARAM) m_dwContext);
|
|
|
|
// Report error
|
|
//
|
|
return ILS_E_NETWORK_DOWN;
|
|
}
|
|
else
|
|
// If dwIPAddress and m_dwIPAddress, alert
|
|
//
|
|
if (dwIPAddress != m_dwIPAddress)
|
|
{
|
|
UpdateIPAddress ();
|
|
}
|
|
|
|
// Send a refresh message to the server and parse the new TTL value
|
|
//
|
|
hr = ::IlsSendRefreshMsg ( &m_ServerInfo,
|
|
STR_DEF_MTG_BASE_DN,
|
|
STR_MTG_TTL,
|
|
m_pszRefreshFilter,
|
|
&m_uTTL);
|
|
if (hr == ILS_E_NEED_RELOGON)
|
|
{
|
|
SetRegLocally ();
|
|
::PostMessage (g_hWndNotify, WM_ILS_MEETING_NEED_RELOGON,
|
|
(WPARAM) this, (LPARAM) m_dwContext);
|
|
}
|
|
else
|
|
if (hr == ILS_E_NETWORK_DOWN)
|
|
{
|
|
SetRegLocally ();
|
|
::PostMessage (g_hWndNotify, WM_ILS_MEETING_NETWORK_DOWN,
|
|
(WPARAM) this, (LPARAM) m_dwContext);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
/* ---------- private methods ----------- */
|
|
|
|
|
|
HRESULT SP_CMeeting::
|
|
CreateRegModArr ( LDAPMod ***pppMod )
|
|
{
|
|
MyAssert (pppMod != NULL);
|
|
|
|
// Calculate the modify array size
|
|
//
|
|
ULONG cStdAttrs = COUNT_ENUM_MTGATTR;
|
|
ULONG cAnyAttrs = m_MtgInfo.AnyAttrs.cAttrsToAdd;
|
|
ULONG cTotal = cStdAttrs + cAnyAttrs;
|
|
ULONG cbMod = ::IlsCalcModifyListSize (cTotal);
|
|
|
|
// Allocate modify list
|
|
//
|
|
*pppMod = (LDAPMod **) MemAlloc (cbMod);
|
|
if (*pppMod == NULL)
|
|
return ILS_E_MEMORY;
|
|
|
|
// Lay out the modify array
|
|
//
|
|
LDAPMod **apMod = *pppMod;
|
|
LDAPMod *pMod;
|
|
TCHAR *pszName, *pszValue;
|
|
pszName = m_MtgInfo.AnyAttrs.pszAttrsToAdd;
|
|
for (ULONG i = 0; i < cTotal; i++)
|
|
{
|
|
pMod = ::IlsGetModifyListMod (pppMod, cTotal, i);
|
|
pMod->mod_op = LDAP_MOD_ADD;
|
|
apMod[i] = pMod;
|
|
|
|
if (i < cStdAttrs)
|
|
{
|
|
// Put standard attributes
|
|
//
|
|
::MtgFillModArrAttr (pMod, &m_MtgInfo, i);
|
|
}
|
|
else
|
|
{
|
|
// Put extended attributes
|
|
//
|
|
pszValue = pszName + lstrlen (pszName) + 1;
|
|
::IlsFillModifyListItem (pMod, pszName, pszValue);
|
|
pszName = pszValue + lstrlen (pszValue) + 1;
|
|
}
|
|
}
|
|
|
|
// Put null to terminate modify list
|
|
//
|
|
apMod[cTotal] = NULL;
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
|
|
/* ---------- helper functions ----------- */
|
|
|
|
|
|
HRESULT
|
|
MtgSetAttrs (
|
|
SERVER_INFO *pServerInfo,
|
|
TCHAR *pszMtgName,
|
|
LDAP_MEETINFO *pInfo,
|
|
ULONG uRespID )
|
|
{
|
|
MyAssert (pServerInfo != NULL);
|
|
MyAssert (MyIsGoodString (pszMtgName));
|
|
MyAssert (pInfo != NULL);
|
|
|
|
// Cannot change lMeetingPlaceType, lAttendeeType, and MeetingID
|
|
//
|
|
if (pInfo->lMeetingPlaceType != INVALID_MEETING_TYPE ||
|
|
pInfo->lAttendeeType != INVALID_ATTENDEE_TYPE ||
|
|
pInfo->uOffsetMeetingPlaceID != INVALID_OFFSET)
|
|
{
|
|
return ILS_E_PARAMETER;
|
|
}
|
|
|
|
// Initialize locals
|
|
//
|
|
TCHAR *pszDN = NULL;
|
|
LDAPMod **ppMod = NULL;
|
|
SP_CSession *pSession = NULL;
|
|
ULONG uMsgID = (ULONG) -1;
|
|
|
|
MTG_INFO MtgInfo;
|
|
ZeroMemory (&MtgInfo, sizeof (MtgInfo));
|
|
|
|
// Cache the meeting info
|
|
//
|
|
HRESULT hr = MtgCacheInfo (pInfo, &MtgInfo);
|
|
if (hr != S_OK)
|
|
goto MyExit;
|
|
|
|
// Build DN for meeting
|
|
//
|
|
pszDN = IlsBuildDN (pServerInfo->pszBaseDN,
|
|
(TCHAR *) &c_szMtgDefC[0],
|
|
(TCHAR *) &c_szDefO[0],
|
|
pszMtgName,
|
|
(TCHAR *) &c_szRTConf[0]);
|
|
if (pszDN == NULL)
|
|
{
|
|
hr = ILS_E_MEMORY;
|
|
goto MyExit;
|
|
}
|
|
|
|
// Build modify array for ldap_modify()
|
|
//
|
|
hr = MtgCreateSetAttrsModArr (&ppMod, &MtgInfo);
|
|
if (hr != S_OK)
|
|
goto MyExit;
|
|
MyAssert (ppMod != NULL);
|
|
|
|
// Get the session object
|
|
//
|
|
LDAP *ld;
|
|
hr = g_pSessionContainer->GetSession (&pSession, pServerInfo);
|
|
if (hr == S_OK)
|
|
{
|
|
MyAssert (pSession != NULL);
|
|
|
|
// Get the ldap session
|
|
//
|
|
ld = pSession->GetLd ();
|
|
MyAssert (ld != NULL);
|
|
|
|
// Send the data over the wire
|
|
//
|
|
uMsgID = ldap_modify (ld, pszDN, ppMod);
|
|
if (uMsgID == (ULONG) -1)
|
|
{
|
|
hr = ::LdapError2Hresult (ld->ld_errno);
|
|
}
|
|
}
|
|
|
|
// Report failure if so
|
|
//
|
|
if (hr != S_OK)
|
|
goto MyExit;
|
|
|
|
// Construct pending info
|
|
//
|
|
RESP_INFO ri;
|
|
FillDefRespInfo (&ri, uRespID, ld, uMsgID, INVALID_MSG_ID);
|
|
ri.uNotifyMsg = WM_ILS_SET_MEETING_INFO;
|
|
|
|
// Remember the pending request
|
|
//
|
|
hr = g_pRespQueue->EnterRequest (pSession, &ri);
|
|
if (hr != S_OK)
|
|
{
|
|
MyAssert (FALSE);
|
|
goto MyExit;
|
|
}
|
|
|
|
MyExit:
|
|
|
|
MemFree (pszDN);
|
|
MemFree (ppMod);
|
|
IlsReleaseAnyAttrsPrefix (&(MtgInfo.AnyAttrs));
|
|
|
|
if (hr != S_OK)
|
|
{
|
|
if (uMsgID != (ULONG) -1)
|
|
::ldap_abandon (ld, uMsgID);
|
|
|
|
if (pSession != NULL)
|
|
pSession->Disconnect ();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
VOID
|
|
MtgFillModArrAttr (
|
|
LDAPMod *pMod,
|
|
MTG_INFO *pMtgInfo,
|
|
INT nIndex )
|
|
{
|
|
MyAssert (pMod != NULL);
|
|
MyAssert (pMtgInfo != NULL);
|
|
MyAssert (0 <= nIndex && nIndex <= COUNT_ENUM_MTGATTR);
|
|
|
|
IlsFillModifyListItem ( pMod,
|
|
(TCHAR *) c_apszMtgStdAttrNames[nIndex],
|
|
pMtgInfo->apszStdAttrValues[nIndex]);
|
|
}
|
|
|
|
|
|
HRESULT
|
|
MtgCreateSetAttrsModArr (
|
|
LDAPMod ***pppMod,
|
|
MTG_INFO *pMtgInfo )
|
|
{
|
|
MyAssert (pppMod != NULL);
|
|
|
|
HRESULT hr;
|
|
DWORD dwFlags = pMtgInfo->dwFlags;
|
|
ULONG cTotal = pMtgInfo->AnyAttrs.cAttrsToAdd +
|
|
pMtgInfo->AnyAttrs.cAttrsToModify +
|
|
pMtgInfo->AnyAttrs.cAttrsToRemove;
|
|
|
|
// Lay out the modify array for modifying standard/extended attributes
|
|
//
|
|
hr = IlsFillDefStdAttrsModArr (pppMod,
|
|
dwFlags,
|
|
COUNT_ENUM_MTGINFO,
|
|
&cTotal,
|
|
ISBU_MODOP_MODIFY_USER,
|
|
MtgGetPrefixCount (),
|
|
MtgGetPrefixString ());
|
|
if (hr != S_OK)
|
|
return hr;
|
|
|
|
// Start to fill standard attributes
|
|
//
|
|
ULONG i = MtgGetPrefixCount ();
|
|
LDAPMod **apMod = *pppMod;
|
|
|
|
if (dwFlags & MTGOBJ_F_NAME)
|
|
MtgFillModArrAttr (apMod[i++], pMtgInfo, ENUM_MTGATTR_CN);
|
|
|
|
if (dwFlags & MTGOBJ_F_MTG_TYPE)
|
|
MtgFillModArrAttr (apMod[i++], pMtgInfo, ENUM_MTGATTR_MTG_TYPE);
|
|
|
|
if (dwFlags & MTGOBJ_F_MEMBER_TYPE)
|
|
MtgFillModArrAttr (apMod[i++], pMtgInfo, ENUM_MTGATTR_MEMBER_TYPE);
|
|
|
|
if (dwFlags & MTGOBJ_F_DESCRIPTION)
|
|
MtgFillModArrAttr (apMod[i++], pMtgInfo, ENUM_MTGATTR_DESCRIPTION);
|
|
|
|
if (dwFlags & MTGOBJ_F_HOST_NAME)
|
|
MtgFillModArrAttr (apMod[i++], pMtgInfo, ENUM_MTGATTR_HOST_NAME);
|
|
|
|
if (dwFlags & MTGOBJ_F_IP_ADDRESS)
|
|
MtgFillModArrAttr (apMod[i++], pMtgInfo, ENUM_MTGATTR_IP_ADDRESS);
|
|
|
|
// Start to fill extended attributes
|
|
//
|
|
::IlsFillModifyListForAnyAttrs (apMod, &i, &(pMtgInfo->AnyAttrs));
|
|
|
|
MyAssert (i == cTotal);
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
HRESULT
|
|
MtgCacheInfo (
|
|
LDAP_MEETINFO *pInfo,
|
|
MTG_INFO *pMtgInfo )
|
|
{
|
|
MyAssert (pInfo != NULL);
|
|
MyAssert (pMtgInfo != NULL);
|
|
|
|
// Release the previous prefix for extended attribute names
|
|
//
|
|
IlsReleaseAnyAttrsPrefix (&(pMtgInfo->AnyAttrs));
|
|
|
|
// Clean up the buffer
|
|
//
|
|
ZeroMemory (pMtgInfo, sizeof (*pMtgInfo));
|
|
|
|
// Start to cache mtg standard attributes
|
|
//
|
|
|
|
if (pInfo->lMeetingPlaceType != INVALID_MEETING_TYPE)
|
|
{
|
|
GetLongString (pInfo->lMeetingPlaceType, &(pMtgInfo->szMtgType[0]));
|
|
pMtgInfo->apszStdAttrValues[ENUM_MTGATTR_MTG_TYPE] = &(pMtgInfo->szMtgType[0]);
|
|
pMtgInfo->dwFlags |= MTGOBJ_F_MTG_TYPE;
|
|
}
|
|
|
|
if (pInfo->lAttendeeType != INVALID_ATTENDEE_TYPE)
|
|
{
|
|
GetLongString (pInfo->lAttendeeType, &(pMtgInfo->szMemberType[0]));
|
|
pMtgInfo->apszStdAttrValues[ENUM_MTGATTR_MEMBER_TYPE] = &(pMtgInfo->szMemberType[0]);
|
|
pMtgInfo->dwFlags |= MTGOBJ_F_MEMBER_TYPE;
|
|
}
|
|
|
|
if (pInfo->uOffsetMeetingPlaceID != INVALID_OFFSET)
|
|
{
|
|
pMtgInfo->apszStdAttrValues[ENUM_MTGATTR_CN] =
|
|
(TCHAR *) (((BYTE *) pInfo) + pInfo->uOffsetMeetingPlaceID);
|
|
pMtgInfo->dwFlags |= MTGOBJ_F_NAME;
|
|
}
|
|
|
|
if (pInfo->uOffsetDescription != INVALID_OFFSET)
|
|
{
|
|
pMtgInfo->apszStdAttrValues[ENUM_MTGATTR_DESCRIPTION] =
|
|
(TCHAR *) (((BYTE *) pInfo) + pInfo->uOffsetDescription);
|
|
pMtgInfo->dwFlags |= MTGOBJ_F_DESCRIPTION;
|
|
}
|
|
|
|
if (pInfo->uOffsetHostName != INVALID_OFFSET)
|
|
{
|
|
pMtgInfo->apszStdAttrValues[ENUM_MTGATTR_HOST_NAME] =
|
|
(TCHAR *) (((BYTE *) pInfo) + pInfo->uOffsetHostName);
|
|
pMtgInfo->dwFlags |= MTGOBJ_F_HOST_NAME;
|
|
}
|
|
|
|
if (pInfo->uOffsetHostIPAddress != INVALID_OFFSET)
|
|
{
|
|
pMtgInfo->apszStdAttrValues[ENUM_MTGATTR_IP_ADDRESS] =
|
|
(TCHAR *) (((BYTE *) pInfo) + pInfo->uOffsetHostIPAddress);
|
|
pMtgInfo->dwFlags |= MTGOBJ_F_IP_ADDRESS;
|
|
}
|
|
|
|
// Start to cache mtg extended attributes
|
|
//
|
|
|
|
if (pInfo->uOffsetAttrsToAdd != INVALID_OFFSET &&
|
|
pInfo->cAttrsToAdd != 0)
|
|
{
|
|
pMtgInfo->AnyAttrs.cAttrsToAdd = pInfo->cAttrsToAdd;
|
|
pMtgInfo->AnyAttrs.pszAttrsToAdd =
|
|
(TCHAR *) (((BYTE *) pInfo) + pInfo->uOffsetAttrsToAdd);
|
|
}
|
|
|
|
if (pInfo->uOffsetAttrsToModify != INVALID_OFFSET &&
|
|
pInfo->cAttrsToModify != 0)
|
|
{
|
|
pMtgInfo->AnyAttrs.cAttrsToModify = pInfo->cAttrsToModify;
|
|
pMtgInfo->AnyAttrs.pszAttrsToModify =
|
|
(TCHAR *) (((BYTE *) pInfo) + pInfo->uOffsetAttrsToModify);
|
|
}
|
|
|
|
if (pInfo->uOffsetAttrsToRemove != INVALID_OFFSET &&
|
|
pInfo->cAttrsToRemove != 0)
|
|
{
|
|
pMtgInfo->AnyAttrs.cAttrsToRemove = pInfo->cAttrsToRemove;
|
|
pMtgInfo->AnyAttrs.pszAttrsToRemove =
|
|
(TCHAR *) (((BYTE *) pInfo) + pInfo->uOffsetAttrsToRemove);
|
|
}
|
|
|
|
// Create prefix for extended attribute names
|
|
//
|
|
return IlsCreateAnyAttrsPrefix (&(pMtgInfo->AnyAttrs));
|
|
}
|
|
|
|
|
|
HRESULT
|
|
MtgUpdateMembers (
|
|
ULONG uNotifyMsg,
|
|
SERVER_INFO *pServerInfo,
|
|
TCHAR *pszMtgName,
|
|
ULONG cMembers,
|
|
TCHAR *pszMemberNames,
|
|
ULONG uRespID )
|
|
{
|
|
MyAssert ( uNotifyMsg == WM_ILS_ADD_ATTENDEE ||
|
|
uNotifyMsg == WM_ILS_REMOVE_ATTENDEE);
|
|
|
|
MyAssert (pServerInfo != NULL);
|
|
MyAssert (MyIsGoodString (pszMtgName));
|
|
MyAssert (MyIsGoodString (pszMemberNames));
|
|
|
|
// Initialize locals
|
|
//
|
|
HRESULT hr = S_OK;
|
|
TCHAR *pszDN = NULL;
|
|
LDAPMod **ppMod = NULL;
|
|
SP_CSession *pSession = NULL;
|
|
ULONG uMsgID = (ULONG) -1;
|
|
|
|
// Build DN for meeting
|
|
//
|
|
pszDN = IlsBuildDN (pServerInfo->pszBaseDN,
|
|
(TCHAR *) &c_szMtgDefC[0],
|
|
(TCHAR *) &c_szDefO[0],
|
|
pszMtgName,
|
|
(TCHAR *) &c_szRTConf[0]);
|
|
if (pszDN == NULL)
|
|
return ILS_E_MEMORY;
|
|
|
|
// Build modify array for ldap_modify()
|
|
//
|
|
hr = MtgCreateUpdateMemberModArr ( uNotifyMsg,
|
|
&ppMod,
|
|
cMembers,
|
|
pszMemberNames);
|
|
if (hr != S_OK)
|
|
goto MyExit;
|
|
MyAssert (ppMod != NULL);
|
|
|
|
// Get the session object
|
|
//
|
|
LDAP *ld;
|
|
hr = g_pSessionContainer->GetSession (&pSession, pServerInfo);
|
|
if (hr == S_OK)
|
|
{
|
|
MyAssert (pSession != NULL);
|
|
|
|
// Get the ldap session
|
|
//
|
|
ld = pSession->GetLd ();
|
|
MyAssert (ld != NULL);
|
|
|
|
// Send the data over the wire
|
|
//
|
|
uMsgID = ldap_modify (ld, pszDN, ppMod);
|
|
if (uMsgID == (ULONG) -1)
|
|
{
|
|
hr = ::LdapError2Hresult (ld->ld_errno);
|
|
}
|
|
}
|
|
|
|
// Report failure if so
|
|
//
|
|
if (hr != S_OK)
|
|
goto MyExit;
|
|
|
|
// Construct pending info
|
|
//
|
|
RESP_INFO ri;
|
|
FillDefRespInfo (&ri, uRespID, ld, uMsgID, INVALID_MSG_ID);
|
|
ri.uNotifyMsg = uNotifyMsg;
|
|
|
|
// Remember the pending request
|
|
//
|
|
hr = g_pRespQueue->EnterRequest (pSession, &ri);
|
|
if (hr != S_OK)
|
|
{
|
|
MyAssert (FALSE);
|
|
goto MyExit;
|
|
}
|
|
|
|
MyExit:
|
|
|
|
MemFree (pszDN);
|
|
MemFree (ppMod);
|
|
|
|
if (hr != S_OK)
|
|
{
|
|
if (uMsgID != (ULONG) -1)
|
|
::ldap_abandon (ld, uMsgID);
|
|
|
|
if (pSession != NULL)
|
|
pSession->Disconnect ();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT
|
|
MtgCreateUpdateMemberModArr (
|
|
ULONG uNotifyMsg,
|
|
LDAPMod ***pppMod,
|
|
ULONG cMembers,
|
|
TCHAR *pszMemberNames )
|
|
{
|
|
MyAssert (pppMod != NULL);
|
|
MyAssert (pszMemberNames != NULL);
|
|
|
|
// Get meeting object prefix
|
|
//
|
|
ULONG cPrefix = MtgGetPrefixCount ();
|
|
TCHAR *pszPrefix = MtgGetPrefixString ();
|
|
|
|
// The total number of attributes is the number of prefix attributes
|
|
// plus the very only ConfMemberList
|
|
//
|
|
ULONG cStdAttrs = 1;
|
|
ULONG cTotal = cPrefix + cStdAttrs;
|
|
|
|
// Calculate the modify array's total size
|
|
//
|
|
ULONG cbMod = IlsCalcModifyListSize (cTotal);
|
|
|
|
// Add up for multi-valued attribute
|
|
//
|
|
cbMod += cStdAttrs * (cMembers - 1) * sizeof (TCHAR *);
|
|
|
|
// Allocate the modify array
|
|
//
|
|
LDAPMod **apMod = *pppMod = (LDAPMod **) MemAlloc (cbMod);
|
|
if (apMod == NULL)
|
|
return ILS_E_MEMORY;
|
|
|
|
// Fill in the modify list
|
|
//
|
|
LDAPMod *pMod;
|
|
BYTE *pbData = (BYTE *) apMod + (cTotal + 1) * sizeof (LDAPMod *);
|
|
ULONG uDispPrefix = sizeof (LDAPMod) + 2 * sizeof (TCHAR *);
|
|
ULONG uDispStdAttrs = sizeof (LDAPMod) + (cMembers + 1) * sizeof (TCHAR *);
|
|
for (ULONG uOffset = 0, i = 0; i < cTotal; i++)
|
|
{
|
|
// Locate the modify structure
|
|
//
|
|
pMod = (LDAPMod *) (pbData + uOffset);
|
|
apMod[i] = pMod;
|
|
pMod->mod_values = (TCHAR **) (pMod + 1);
|
|
|
|
// Fill in the modify structure
|
|
//
|
|
if (i < cPrefix)
|
|
{
|
|
pMod->mod_op = LDAP_MOD_REPLACE;
|
|
pMod->mod_type = pszPrefix;
|
|
pszPrefix += lstrlen (pszPrefix) + 1;
|
|
*(pMod->mod_values) = pszPrefix;
|
|
pszPrefix += lstrlen (pszPrefix) + 1;
|
|
}
|
|
else
|
|
{
|
|
// Fill in attribute name
|
|
//
|
|
pMod->mod_op = (uNotifyMsg == WM_ILS_ADD_ATTENDEE) ?
|
|
LDAP_MOD_ADD : LDAP_MOD_DELETE;
|
|
pMod->mod_type = (TCHAR *) c_apszMtgStdAttrNames[ENUM_MTGATTR_MEMBERS];
|
|
|
|
// Fill in multi-valued modify array
|
|
//
|
|
for (ULONG j = 0; j < cMembers; j++)
|
|
{
|
|
(pMod->mod_values)[j++] = pszMemberNames;
|
|
pszMemberNames += lstrlen (pszMemberNames) + 1;
|
|
}
|
|
}
|
|
|
|
// Calculate the modify structure's offset relative to the array's end
|
|
//
|
|
uOffset += (i < cPrefix) ? uDispPrefix : uDispStdAttrs;
|
|
}
|
|
|
|
// Fix up the first and the last ones
|
|
//
|
|
IlsFixUpModOp (apMod[0], LDAP_MOD_REPLACE, ISBU_MODOP_MODIFY_APP);
|
|
apMod[cTotal] = NULL;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
#endif // ENABLE_MEETING_PLACE
|
|
|