WindowsXP-SP1/enduser/netmeeting/ulsldap/spnotify.cpp

2830 lines
63 KiB
C++
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* ----------------------------------------------------------------------
Module: ULS.DLL (Service Provider)
File: spnotify.cpp
Content: This file contains the notification handlers.
History:
10/15/96 Chu, Lon-Chan [lonchanc]
Created.
Copyright (c) Microsoft Corporation 1996-1997
---------------------------------------------------------------------- */
#include "ulsp.h"
#include "spinc.h"
typedef struct
{
TCHAR *pszName;
TCHAR *pszValue;
}
ATTR_PAIR;
typedef struct
{
ULONG cMaxAttrs;
ULONG cCurrAttrs;
ATTR_PAIR aPairs[1];
}
ATTR_PAIRS;
typedef struct
{
CLIENT_INFO ClientInfo;
ATTR_PAIRS Attrs;
}
CLIENT_INFO_ATTRS;
#ifdef ENABLE_MEETING_PLACE
typedef struct
{
MTG_INFO MtgInfo;
ATTR_PAIRS Attrs;
}
MTG_INFO_ATTRS;
#endif
ULONG
GetUniqueNotifyID ( VOID )
{
// Always positive number
//
if (g_uRespID & 0x80000000UL)
g_uRespID = 1;
return g_uRespID++;
}
BOOL
NotifyGeneric (
HRESULT hrServer,
SP_CResponse *pItem )
{
MyAssert (pItem != NULL);
// Get the pending info
//
RESP_INFO *pInfo = pItem->GetRespInfo ();
MyAssert (pInfo != NULL);
// Do not use the result (pLdapMsg)
//
// Check dependency such as modify/modrdn
//
if (pInfo->uMsgID[0] != INVALID_MSG_ID)
{
// Do we wait for the second result?
// If so, remember the hr from the first result.
//
if (pInfo->uMsgID[1] != INVALID_MSG_ID)
{
// We need two results; the first one just comes in.
// We still need to wait for the second one
//
pInfo->uMsgID[0] = INVALID_MSG_ID;
pInfo->hrDependency = hrServer;
// Don't destroy this item
//
return FALSE;
}
}
else
{
// This is the second result
//
MyAssert (pInfo->uMsgID[1] != INVALID_MSG_ID);
// Propagate the hr from the first result if needed
//
if (pInfo->hrDependency != S_OK)
hrServer = pInfo->hrDependency;
}
// Post the result to the com layer
//
PostMessage (g_hWndNotify, pInfo->uNotifyMsg, pInfo->uRespID, hrServer);
// Destroy this pending item
//
return TRUE;
}
BOOL
NotifyRegister (
HRESULT hrServer,
SP_CResponse *pItem )
{
MyAssert (pItem != NULL);
// Get pending info
//
RESP_INFO *pInfo = pItem->GetRespInfo ();
MyAssert (pInfo != NULL);
// Get the object of user/app/prot/mtg
//
HANDLE hObject = pInfo->hObject;
MyAssert (hObject != NULL);
// Do not use the result (pLdapMsg)
//
// Check dependency such as modify/modrdn
//
if (pInfo->uMsgID[0] != INVALID_MSG_ID)
{
// Do we wait for the second result?
// If so, remember the hr from the first result.
//
if (pInfo->uMsgID[1] != INVALID_MSG_ID)
{
// We need two results; the first one just comes in.
// We still need to wait for the second one
//
pInfo->uMsgID[0] = INVALID_MSG_ID;
pInfo->hrDependency = hrServer;
// Don't destroy this item
//
return FALSE;
}
}
else
{
// This is the second result
//
MyAssert (pInfo->uMsgID[1] != INVALID_MSG_ID);
// Propagate the hr from the first result if needed
//
if (pInfo->hrDependency != S_OK)
hrServer = pInfo->hrDependency;
}
// Notify the object of success/failure
//
SP_CClient *pClient;
SP_CProtocol *pProt;
#ifdef ENABLE_MEETING_PLACE
SP_CMeeting *pMtg;
#endif
if (hrServer != S_OK)
{
// Release the object when failure
//
switch (pInfo->uNotifyMsg)
{
case WM_ILS_REGISTER_CLIENT:
pClient = (SP_CClient *) hObject;
if (pClient->IsValidObject ())
{
pClient->Release ();
}
break;
case WM_ILS_REGISTER_PROTOCOL:
pProt = (SP_CProtocol *) hObject;
if (pProt->IsValidObject ())
{
pProt->Release ();
}
break;
#ifdef ENABLE_MEETING_PLACE
case WM_ILS_REGISTER_MEETING:
pMtg = (SP_CMeeting *) hObject;
if (pMtg->IsValidObject ())
{
pMtg->Release ();
}
break;
#endif
default:
MyAssert (FALSE);
break;
}
}
else
{
// Set as successful registration when success
//
switch (pInfo->uNotifyMsg)
{
case WM_ILS_REGISTER_CLIENT:
pClient = (SP_CClient *) hObject;
if (pClient->IsValidObject ())
{
pClient->SetRegRemotely ();
if (g_pRefreshScheduler != NULL)
{
g_pRefreshScheduler->EnterClientObject (pClient);
}
else
{
MyAssert (FALSE);
}
}
break;
case WM_ILS_REGISTER_PROTOCOL:
pProt = (SP_CProtocol *) hObject;
if (pProt->IsValidObject ())
{
pProt->SetRegRemotely ();
}
break;
#ifdef ENABLE_MEETING_PLACE
case WM_ILS_REGISTER_MEETING:
pMtg = (SP_CMeeting *) hObject;
if (pMtg->IsValidObject ())
{
pMtg->SetRegRemotely ();
if (g_pRefreshScheduler != NULL)
{
g_pRefreshScheduler->EnterMtgObject (pMtg);
}
else
{
MyAssert (FALSE);
}
}
break;
#endif
default:
MyAssert (FALSE);
break;
}
}
// Post the result to the com layer
//
PostMessage (g_hWndNotify, pInfo->uNotifyMsg, pInfo->uRespID, (LPARAM) hrServer);
// Destroy this pending item
//
return TRUE;
}
/* =========== ENUMERATION ============ */
typedef struct
{
ULONG uEnumUsers; // WM_ILS_ENUM_USERS, WM_ILS_ENUM_USERINFOS, or 0
ULONG cItems;
ULONG cbEntrySize;
BYTE bData[8]; // data starting from here
}
ENUM_LIST;
extern HRESULT CacheEnumInfos ( ULONG uNotifyMsg, LDAP *ld, LDAPMessage *pEntry, VOID *p );
extern VOID BuildEnumObjectNames ( LDAP_ENUM *pEnum, ENUM_LIST *pEnumList );
extern VOID BuildEnumClientInfos ( LDAP_ENUM *pEnum, ENUM_LIST *pEnumList );
extern VOID SizeEnumClientInfos ( ULONG *pcbTotalSize, CLIENT_INFO_ATTRS *pcia );
extern VOID TotalSizeEnumObjectNames ( ULONG *pcbTotalSize, ULONG cEntries, TCHAR **appszObjectNames[] );
extern VOID FreeStdAttrCache ( TCHAR *apszStdAttrValues[], ULONG cStdAttrs );
extern VOID FreeAttrPairArrayCache ( ATTR_PAIR aAttrPair[], ULONG cPairs );
extern VOID CacheAnyAttrNamesInAttrPairs ( ULONG cNames, TCHAR *pszSrcNameList, ATTR_PAIR aAttrPairs[] );
#ifdef ENABLE_MEETING_PLACE
extern VOID BuildEnumMtgInfos ( LDAP_ENUM *pEnum, ENUM_LIST *pEnumList );
extern VOID SizeEnumMtgInfos ( ULONG *pcbTotalSize, MTG_INFO_ATTRS *pmia );
#endif
BOOL NotifyEnumX (
ULONG uEnumType,
HRESULT hrServer,
SP_CResponse *pItem,
TCHAR *pszRetAttrName ) // returned attribute's name
{
MyAssert (pItem != NULL);
#if defined (DEBUG) || defined (_DEBUG)
// Consistency checks
//
switch (uEnumType)
{
case WM_ILS_ENUM_CLIENTS:
#ifdef ENABLE_MEETING_PLACE
case WM_ILS_ENUM_MEETINGS:
#endif
MyAssert (pszRetAttrName != NULL && *pszRetAttrName != TEXT ('\0'));
break;
case WM_ILS_ENUM_CLIENTINFOS:
#ifdef ENABLE_MEETING_PLACE
case WM_ILS_ENUM_MEETINGINFOS:
#endif
MyAssert (pszRetAttrName == NULL);
break;
default:
MyAssert (FALSE);
break;
}
#endif
// Get pending info
//
RESP_INFO *pInfo = pItem->GetRespInfo ();
MyAssert (pInfo != NULL);
// Initialize minimal info
//
LDAP_ENUM *pEnum = NULL;
ENUM_LIST *pEnumList = NULL;
// If error, simply report the error
//
if (hrServer != S_OK)
goto MyExit;
// Get the ldap result
//
LDAPMessage *pLdapMsg;
pLdapMsg = pItem->GetResult ();
if (pLdapMsg == NULL)
{
MyAssert (FALSE);
hrServer = ILS_E_POINTER;
goto MyExit;
}
// Get ld
//
LDAP *ld;
ld = pItem->GetLd ();
if (ld == NULL)
{
MyAssert (FALSE);
hrServer = ILS_E_HANDLE;
goto MyExit;
}
// Initialize the total size of LDAP_ENUM
//
ULONG cbTotalSize;
cbTotalSize = sizeof (LDAP_ENUM) + // the minimal info
sizeof (TCHAR); // the last null terminator
// Let's get the count of entries in this result set
//
ULONG cEntries, i;
cEntries = ldap_count_entries (ld, pLdapMsg);
// Return now if there is nothing to handle
//
if (cEntries <= 0)
{
// I want to make sure this case happens or not
//
MyAssert (cEntries == 0);
// Simply return without deleting this pending item
//
return FALSE;
}
// In the following, we only deal with the case (cEntries > 0)
//
// Calculate enum list size
//
ULONG cbEntrySize , cbSizeEnumList;
switch (uEnumType)
{
case WM_ILS_ENUM_CLIENTINFOS:
cbEntrySize = sizeof (CLIENT_INFO_ATTRS) +
pInfo->cAnyAttrs * sizeof (ATTR_PAIR);
break;
#ifdef ENABLE_MEETING_PLACE
case WM_ILS_ENUM_MEETINGINFOS:
cbEntrySize = sizeof (MTG_INFO_ATTRS) +
pInfo->cAnyAttrs * sizeof (ATTR_PAIR);
break;
#endif
default:
cbEntrySize = sizeof (TCHAR **);
break;
}
cbSizeEnumList = sizeof (ENUM_LIST) + cEntries * cbEntrySize;
// Allocate the enum list that is a temporary cache
// for all attributes from wldap32.dll
//
pEnumList = (ENUM_LIST *) MemAlloc (cbSizeEnumList);
if (pEnumList == NULL)
{
// Fails probably due to insane cbSizeEnumList
//
MyAssert (FALSE);
hrServer = ILS_E_MEMORY;
goto MyExit;
}
// Fill in enum list
//
pEnumList->uEnumUsers = uEnumType;
pEnumList->cItems = cEntries;
pEnumList->cbEntrySize = cbEntrySize;
// Fill in names of extended attributes if needed
//
if (pInfo->cAnyAttrs > 0)
{
switch (uEnumType)
{
case WM_ILS_ENUM_CLIENTINFOS:
for (i = 0; i < cEntries; i++)
{
CLIENT_INFO_ATTRS *p = (CLIENT_INFO_ATTRS *) (&(pEnumList->bData[0]) + i * cbEntrySize);
p->Attrs.cMaxAttrs = pInfo->cAnyAttrs;
CacheAnyAttrNamesInAttrPairs ( pInfo->cAnyAttrs,
pInfo->pszAnyAttrNameList,
&(p->Attrs.aPairs[0]));
}
break;
#ifdef ENABLE_MEETING_PLACE
case WM_ILS_ENUM_MEETINGINFOS:
for (i = 0; i < cEntries; i++)
{
MTG_INFO_ATTRS *p = (MTG_INFO_ATTRS *) (&(pEnumList->bData[0]) + i * cbEntrySize);
p->Attrs.cMaxAttrs = pInfo->cAnyAttrs;
CacheAnyAttrNamesInAttrPairs ( pInfo->cAnyAttrs,
pInfo->pszAnyAttrNameList,
&(p->Attrs.aPairs[0]));
}
break;
#endif
default:
break;
}
}
// Get the first entry
//
LDAPMessage *pEntry;
pEntry = ldap_first_entry (ld, pLdapMsg);
if (pEntry == NULL)
{
MyAssert (FALSE);
hrServer = ILS_E_MEMORY;
goto MyExit;
}
// Cache the attributes in the first entry
//
TCHAR ***appszObjectNames;
switch (uEnumType)
{
case WM_ILS_ENUM_CLIENTINFOS:
#ifdef ENABLE_MEETING_PLACE
case WM_ILS_ENUM_MEETINGINFOS:
#endif
hrServer = CacheEnumInfos (uEnumType, ld, pEntry, (VOID *) &(pEnumList->bData[0]));
if (hrServer != S_OK)
{
MyAssert (FALSE);
goto MyExit;
}
break;
default:
appszObjectNames = (TCHAR ***) &(pEnumList->bData[0]);
appszObjectNames[0] = my_ldap_get_values (ld, pEntry, pszRetAttrName);
if (appszObjectNames[0] == NULL)
{
MyAssert (FALSE);
hrServer = ILS_E_MEMORY;
goto MyExit;
}
break;
} // switch (uEnumType)
// Loop through the other entries
//
for (i = 1; i < cEntries; i++)
{
// Next entry, please
//
pEntry = ldap_next_entry (ld, pEntry);
if (pEntry == NULL)
{
MyAssert (FALSE);
// Failed, adjust the count to return partial result
//
pEnumList->cItems = cEntries = i;
break;
}
// Cache the attributes in the subsequent entries
//
switch (uEnumType)
{
case WM_ILS_ENUM_CLIENTINFOS:
#ifdef ENABLE_MEETING_PLACE
case WM_ILS_ENUM_MEETINGINFOS:
#endif
hrServer = CacheEnumInfos (uEnumType, ld, pEntry, (CLIENT_INFO_ATTRS *)
(&(pEnumList->bData[0]) + i * cbEntrySize));
if (hrServer != S_OK)
{
MyAssert (FALSE);
goto MyExit;
}
break;
default:
appszObjectNames[i] = my_ldap_get_values (ld, pEntry, pszRetAttrName);
if (appszObjectNames[i] == NULL)
{
MyAssert (FALSE);
hrServer = ILS_E_MEMORY;
goto MyExit;
}
break;
} // switch (uEnumType)
} // for (i = 1; i < cEntries; i++)
// We just cache all the attribute names and values.
// Now, we need to calculate the total size of the return buffer.
//
// Calculate the total size of the LDAP_ENUM structure...
//
switch (uEnumType)
{
case WM_ILS_ENUM_CLIENTINFOS:
for (i = 0; i < cEntries; i++)
{
SizeEnumClientInfos (&cbTotalSize, (CLIENT_INFO_ATTRS *)
(&(pEnumList->bData[0]) + i * cbEntrySize));
}
break;
#ifdef ENABLE_MEETING_PLACE
case WM_ILS_ENUM_MEETINGINFOS:
for (i = 0; i < cEntries; i++)
{
SizeEnumMtgInfos (&cbTotalSize, (MTG_INFO_ATTRS *)
(&(pEnumList->bData[0]) + i * cbEntrySize));
}
break;
#endif
default:
TotalSizeEnumObjectNames (&cbTotalSize, cEntries, &(appszObjectNames[0]));
break;
} // switch (uEnumType)
// Allocate the returned LDAP_ENUM structure
//
pEnum = (LDAP_ENUM *) MemAlloc (cbTotalSize);
if (pEnum == NULL)
{
// Fails probably due to insane cbTotalSize
//
MyAssert (FALSE);
hrServer = ILS_E_MEMORY;
goto MyExit;
}
// Fill in LDAP_ENUM common fields
//
pEnum->uSize = sizeof (*pEnum);
pEnum->hResult = hrServer;
pEnum->cItems = cEntries;
pEnum->uOffsetItems = sizeof (*pEnum);
// Fill in LDAP_ENUM items
//
switch (uEnumType)
{
case WM_ILS_ENUM_CLIENTINFOS:
BuildEnumClientInfos (pEnum, pEnumList);
break;
#ifdef ENABLE_MEETING_PLACE
case WM_ILS_ENUM_MEETINGINFOS:
BuildEnumMtgInfos (pEnum, pEnumList);
break;
#endif
default:
BuildEnumObjectNames (pEnum, pEnumList);
break;
}
MyAssert (hrServer == S_OK);
MyExit:
// Free the temporary cache
//
if (pEnumList != NULL)
{
switch (uEnumType)
{
case WM_ILS_ENUM_CLIENTINFOS:
for (i = 0; i < pEnumList->cItems; i++)
{
CLIENT_INFO_ATTRS *p = (CLIENT_INFO_ATTRS *)
(&(pEnumList->bData[0]) + i * cbEntrySize);
// Free standard attributes
//
FreeStdAttrCache (&(p->ClientInfo.apszStdAttrValues[0]), COUNT_ENUM_DIR_CLIENT_INFO);
// Free extended attributes
//
FreeAttrPairArrayCache (&(p->Attrs.aPairs[0]), pInfo->cAnyAttrs);
}
break;
#ifdef ENABLE_MEETING_PLACE
case WM_ILS_ENUM_MEETINGINFOS:
for (i = 0; i < pEnumList->cItems; i++)
{
MTG_INFO_ATTRS *p = (MTG_INFO_ATTRS *)
(&(pEnumList->bData[0]) + i * cbEntrySize);
// Free standard attributes
//
FreeStdAttrCache (&(p->MtgInfo.apszStdAttrValues[0]), COUNT_ENUM_DIRMTGINFO);
// Free extended attributes
//
FreeAttrPairArrayCache (&(p->Attrs.aPairs[0]), pInfo->cAnyAttrs);
}
break;
#endif
default:
for (i = 0; i < pEnumList->cItems; i++)
{
if (appszObjectNames[i] != NULL)
ldap_value_free (appszObjectNames[i]);
}
break;
}
MemFree (pEnumList);
} // if
// Clean up if failure
//
if (hrServer != S_OK)
{
// Special treatment of enum termination for wldap32.dll
//
if (hrServer == ILS_E_PARAMETER)
{
MemFree (pEnum);
pEnum = NULL; // enum termination
}
else
{
// Make sure we have at least LDAP_ENUM buffer to return
//
if (pEnum != NULL)
ZeroMemory (pEnum, sizeof (*pEnum));
else
pEnum = (LDAP_ENUM *) MemAlloc (sizeof (LDAP_ENUM));
// Set up the LDAP_ENUM info
//
if (pEnum != NULL)
{
pEnum->uSize = sizeof (*pEnum);
pEnum->hResult = hrServer;
}
}
// Force to delete this pending item
//
cEntries = 0;
}
// Post a message to the com layer of this enum result
//
PostMessage (g_hWndNotify, pInfo->uNotifyMsg, pInfo->uRespID, (LPARAM) pEnum);
return (cEntries == 0);
}
BOOL
NotifyEnumClients (
HRESULT hrServer,
SP_CResponse *pItem )
{
return NotifyEnumX (WM_ILS_ENUM_CLIENTS,
hrServer,
pItem,
STR_CLIENT_CN);
}
BOOL
NotifyEnumClientInfos (
HRESULT hrServer,
SP_CResponse *pItem )
{
return NotifyEnumX (WM_ILS_ENUM_CLIENTINFOS,
hrServer,
pItem,
NULL);
}
BOOL NotifyEnumProts ( HRESULT hrServer, SP_CResponse *pItem )
{
MyAssert (pItem != NULL);
// Clean up locals
//
LDAP_ENUM *pEnum = NULL;
TCHAR **apszProtNames = NULL;
// Get the pending info
//
RESP_INFO *pInfo = pItem->GetRespInfo ();
MyAssert (pInfo != NULL);
// If error, simply report the error
//
if (hrServer != S_OK)
goto MyExit;
// Get the ldap result
//
LDAPMessage *pLdapMsg;
pLdapMsg = pItem->GetResult ();
MyAssert (pLdapMsg != NULL);
if (pLdapMsg == NULL)
{
MyAssert (FALSE);
hrServer = ILS_E_POINTER;
goto MyExit;
}
// Get ld
//
LDAP *ld;
ld = pItem->GetLd ();
if (ld == NULL)
{
MyAssert (FALSE);
hrServer = ILS_E_HANDLE;
goto MyExit;
}
// Get the array
//
apszProtNames = my_ldap_get_values (ld, pLdapMsg, STR_PROT_NAME);
if (apszProtNames == NULL)
{
hrServer = ILS_E_NO_SUCH_OBJECT;
goto MyExit;
}
// Initialize minimal info size
//
ULONG cbEnumList;
cbEnumList = sizeof (LDAP_ENUM) + // the minimal info
sizeof (TCHAR); // the last null terminator
// Let's see how many strings in the array
//
ULONG cNames;
for (cNames = 0; apszProtNames[cNames] != NULL; cNames++)
{
cbEnumList += (lstrlen (apszProtNames[cNames]) + 1) * sizeof (TCHAR);
}
// Allocate the enum structure
//
pEnum = (LDAP_ENUM *) MemAlloc (cbEnumList);
if (pEnum == NULL)
{
hrServer = ILS_E_MEMORY;
goto MyExit;
}
// Fill in header
//
pEnum->uSize = sizeof (*pEnum);
pEnum->hResult = hrServer;
pEnum->cItems = cNames;
pEnum->uOffsetItems = sizeof (*pEnum);
// Fill in name strings
//
ULONG i;
TCHAR *pszName;
pszName = (TCHAR *) (pEnum + 1);
for (i = 0; i < cNames; i++)
{
My_lstrcpy (pszName, apszProtNames[i]);
pszName += lstrlen (pszName) + 1;
}
MyAssert (hrServer == S_OK);
MyExit:
// Free the array if allocated
//
if (apszProtNames != NULL)
ldap_value_free (apszProtNames);
// Post messages back to the COM layer
//
if (hrServer != S_OK)
{
// Make sure we have at least LDAP_ENUM buffer to return
//
if (pEnum != NULL)
ZeroMemory (pEnum, sizeof (*pEnum));
else
pEnum = (LDAP_ENUM *) MemAlloc (sizeof (LDAP_ENUM));
// Set up the LDAP_ENUM info
//
if (pEnum != NULL)
{
pEnum->uSize = sizeof (*pEnum);
pEnum->hResult = hrServer;
}
}
// Post a message to the com layer of this enum result
//
PostMessage (g_hWndNotify, pInfo->uNotifyMsg, pInfo->uRespID, (LPARAM) pEnum);
// Terminate enumeration if success
//
if (hrServer == S_OK)
{
PostMessage (g_hWndNotify, pInfo->uNotifyMsg, pInfo->uRespID, (LPARAM) NULL);
}
// Destroy this pending item
//
return TRUE;
}
#ifdef ENABLE_MEETING_PLACE
BOOL NotifyEnumMtgs ( HRESULT hrServer, SP_CResponse *pItem )
{
return NotifyEnumX (WM_ILS_ENUM_MEETINGS,
hrServer,
pItem,
STR_MTG_NAME);
}
#endif
#ifdef ENABLE_MEETING_PLACE
BOOL NotifyEnumMtgInfos ( HRESULT hrServer, SP_CResponse *pItem )
{
return NotifyEnumX (WM_ILS_ENUM_MEETINGINFOS,
hrServer,
pItem,
NULL);
}
#endif
#ifdef ENABLE_MEETING_PLACE
BOOL NotifyEnumAttendees ( HRESULT hrServer, SP_CResponse *pItem )
{
MyAssert (pItem != NULL);
// Get pending info
//
RESP_INFO *pInfo = pItem->GetRespInfo ();
MyAssert (pInfo != NULL);
// Initialize minimal info
//
LDAP_ENUM *pEnum = NULL;
// If error, simply report the error
//
if (hrServer != S_OK)
goto MyExit;
// Get the ldap result
//
LDAPMessage *pLdapMsg;
pLdapMsg = pItem->GetResult ();
if (pLdapMsg == NULL)
{
MyAssert (FALSE);
hrServer = ILS_E_POINTER;
goto MyExit;
}
// Get ld
//
LDAP *ld;
ld = pItem->GetLd ();
if (ld == NULL)
{
MyAssert (FALSE);
hrServer = ILS_E_HANDLE;
goto MyExit;
}
// Initialize the total size of LDAP_ENUM
//
ULONG cbTotalSize;
cbTotalSize = sizeof (LDAP_ENUM) + // the minimal info
sizeof (TCHAR); // the last null terminator
// Get the first entry that we care about
//
LDAPMessage *pEntry;
pEntry = ldap_first_entry (ld, pLdapMsg);
if (pEntry == NULL)
{
MyAssert (FALSE);
hrServer = ILS_E_MEMORY;
goto MyExit;
}
// Get the Members attribute
//
ULONG cItems;
cItems = 0;
TCHAR **apszMembers;
apszMembers = my_ldap_get_values (ld, pEntry, STR_MTG_MEMBERS);
if (apszMembers != NULL)
{
// Find out how many attendees
//
for (TCHAR **ppsz = apszMembers; *ppsz != NULL; ppsz++)
{
cItems++;
cbTotalSize += (lstrlen (*ppsz) + 1) * sizeof (TCHAR);
}
}
// Allocate the returned LDAP_ENUM structure
//
pEnum = (LDAP_ENUM *) MemAlloc (cbTotalSize);
if (pEnum == NULL)
{
// Fails probably due to insane cbTotalSize
//
MyAssert (FALSE);
hrServer = ILS_E_MEMORY;
goto MyExit;
}
// Fill in LDAP_ENUM common fields
//
pEnum->uSize = sizeof (*pEnum);
pEnum->hResult = hrServer;
pEnum->cItems = cItems;
pEnum->uOffsetItems = sizeof (*pEnum);
// Fill in LDAP_ENUM items
//
TCHAR *pszDst;
ULONG i;
pszDst = (TCHAR *) (pEnum + 1);
for (i = 0; i < cItems; i++)
{
lstrcpy (pszDst, apszMembers[i]);
pszDst += lstrlen (pszDst) + 1;
}
MyAssert (hrServer == S_OK);
MyExit:
// Clean up if failure
//
if (hrServer != S_OK)
{
// Make sure we have at least LDAP_ENUM buffer to return
//
if (pEnum != NULL)
ZeroMemory (pEnum, sizeof (*pEnum));
else
pEnum = (LDAP_ENUM *) MemAlloc (sizeof (LDAP_ENUM));
// Fill in the minimal info
//
if (pEnum != NULL)
{
pEnum->uSize = sizeof (*pEnum);
pEnum->hResult = hrServer;
}
}
// Post a message to the com layer of this enum result
//
PostMessage (g_hWndNotify, pInfo->uNotifyMsg, pInfo->uRespID, (LPARAM) pEnum);
// Delete this pending item
//
return TRUE;
}
#endif // ENABLE_MEETING_PLACE
VOID CacheEnumClientInfoAttr (
CLIENT_INFO_ATTRS *puia,
TCHAR *pszAttrName,
TCHAR **ppszAttrValue )
{
ULONG i;
// See if this attribute is arbitrary?
//
if (IlsIsAnyAttrName (pszAttrName) != NULL)
{
// Deal with extended attributes
//
for (i = 0; i < puia->Attrs.cMaxAttrs; i++)
{
if (My_lstrcmpi (pszAttrName, puia->Attrs.aPairs[i].pszName) == 0)
{
puia->Attrs.aPairs[i].pszValue = (TCHAR *) ppszAttrValue;
break;
}
}
}
else
{
// Deal with standard attributes
//
for (i = 0; i < COUNT_ENUM_DIR_CLIENT_INFO; i++)
{
if (My_lstrcmpi (pszAttrName, c_apszClientStdAttrNames[i]) == 0)
{
puia->ClientInfo.apszStdAttrValues[i] = (TCHAR *) ppszAttrValue;
break;
}
}
}
}
#ifdef ENABLE_MEETING_PLACE
VOID CacheEnumMtgInfoAttr (
MTG_INFO_ATTRS *pmia,
TCHAR *pszAttrName,
TCHAR **ppszAttrValue )
{
ULONG i;
// See if this attribute is arbitrary?
//
if (IlsIsAnyAttrName (pszAttrName) != NULL)
{
// Deal with extended attributes
//
for (i = 0; i < pmia->Attrs.cMaxAttrs; i++)
{
if (My_lstrcmpi (pszAttrName, pmia->Attrs.aPairs[i].pszName) == 0)
{
pmia->Attrs.aPairs[i].pszValue = (TCHAR *) ppszAttrValue;
break;
}
}
}
else
{
// Deal with standard attributes
//
for (i = 0; i < COUNT_ENUM_DIRMTGINFO; i++)
{
if (My_lstrcmpi (pszAttrName, c_apszMtgStdAttrNames[i]) == 0)
{
pmia->MtgInfo.apszStdAttrValues[i] = (TCHAR *) ppszAttrValue;
break;
}
}
}
}
#endif // ENABLE_MEETING_PLACE
HRESULT CacheEnumInfos (
ULONG uNotifyMsg,
LDAP *ld,
LDAPMessage *pEntry,
VOID *p )
{
MyAssert (ld != NULL);
MyAssert (pEntry != NULL);
MyAssert (p != NULL);
struct berelement *pContext = NULL;
// Examine the first attribute
//
TCHAR *pszAttrName = ldap_first_attribute (ld, pEntry, &pContext);
TCHAR **ppszAttrValue = ldap_get_values (ld, pEntry, pszAttrName);
if (ppszAttrValue == NULL)
return ILS_E_MEMORY;
// Cache the first attribute
//
switch (uNotifyMsg)
{
case WM_ILS_ENUM_CLIENTINFOS:
CacheEnumClientInfoAttr ( (CLIENT_INFO_ATTRS *) p,
pszAttrName, ppszAttrValue);
break;
#ifdef ENABLE_MEETING_PLACE
case WM_ILS_ENUM_MEETINGINFOS:
CacheEnumMtgInfoAttr ( (MTG_INFO_ATTRS *) p,
pszAttrName, ppszAttrValue);
break;
#endif
default:
MyAssert (FALSE);
break;
}
// Step through the others
//
while ((pszAttrName = ldap_next_attribute (ld, pEntry, pContext))
!= NULL)
{
// Examine the other attributes one by one
//
ppszAttrValue = ldap_get_values (ld, pEntry, pszAttrName);
if (ppszAttrValue == NULL)
return ILS_E_MEMORY;
// Cache the other attributes one by one
//
switch (uNotifyMsg)
{
case WM_ILS_ENUM_CLIENTINFOS:
CacheEnumClientInfoAttr ( (CLIENT_INFO_ATTRS *) p,
pszAttrName, ppszAttrValue);
break;
#ifdef ENABLE_MEETING_PLACE
case WM_ILS_ENUM_MEETINGINFOS:
CacheEnumMtgInfoAttr ( (MTG_INFO_ATTRS *) p,
pszAttrName, ppszAttrValue);
break;
#endif
default:
MyAssert (FALSE);
break;
}
}
return S_OK;
}
VOID
BuildEnumObjectNames (
LDAP_ENUM *pEnum,
ENUM_LIST *pEnumList )
{
MyAssert (pEnum != NULL);
MyAssert (pEnumList != NULL);
ULONG cEntries = pEnum->cItems;
// appszObjectNames are an array of names from server
//
TCHAR *pszName = (TCHAR *) (pEnum + 1);
TCHAR ***appszObjectNames = (TCHAR ***) &(pEnumList->bData[0]);
for (ULONG i = 0; i < cEntries; i++)
{
TCHAR **ppsz = appszObjectNames[i];
if (ppsz != NULL && *ppsz != NULL)
{
My_lstrcpy (pszName, *ppsz);
pszName += lstrlen (pszName) + 1;
}
else
{
*pszName++ = TEXT ('\0'); // empty strings
}
}
}
VOID
BuildEnumClientInfos (
LDAP_ENUM *pEnum,
ENUM_LIST *pEnumList )
{
MyAssert (pEnum != NULL);
MyAssert (pEnumList != NULL);
ULONG i, j;
ULONG cEntries = pEnumList->cItems;
ULONG cbEntrySize = pEnumList->cbEntrySize;
LDAP_CLIENTINFO *plci = (LDAP_CLIENTINFO *) (pEnum + 1);
TCHAR *pszStringBuffer = (TCHAR *) (plci + cEntries);
TCHAR **ppsz;
CLIENT_INFO_ATTRS *p;
ULONG cAttrs;
// Loop through all entries
//
for (i = 0; i < cEntries; i++, plci++)
{
// Get to cached structure
//
p = (CLIENT_INFO_ATTRS *) (&(pEnumList->bData[0]) + i * cbEntrySize);
// Set the size of LDAP_USERINFO
//
plci->uSize = sizeof (*plci);
// Copy the User Name if needed
//
ppsz = (TCHAR **) p->ClientInfo.apszStdAttrValues[ENUM_CLIENTATTR_CN];
if (ppsz != NULL)
{
plci->uOffsetCN = (ULONG)((ULONG_PTR) pszStringBuffer - (ULONG_PTR) plci);
My_lstrcpy (pszStringBuffer, *ppsz);
pszStringBuffer += lstrlen (pszStringBuffer) + 1;
}
// Copy the First Name if needed
//
ppsz = (TCHAR **) p->ClientInfo.apszStdAttrValues[ENUM_CLIENTATTR_FIRST_NAME];
if (ppsz != NULL)
{
plci->uOffsetFirstName = (ULONG)((ULONG_PTR) pszStringBuffer - (ULONG_PTR) plci);
My_lstrcpy (pszStringBuffer, *ppsz);
pszStringBuffer += lstrlen (pszStringBuffer) + 1;
}
// Copy the Last Name if needed
//
ppsz = (TCHAR **) p->ClientInfo.apszStdAttrValues[ENUM_CLIENTATTR_LAST_NAME];
if (ppsz != NULL)
{
plci->uOffsetLastName = (ULONG)((ULONG_PTR) pszStringBuffer - (ULONG_PTR) plci);
My_lstrcpy (pszStringBuffer, *ppsz);
pszStringBuffer += lstrlen (pszStringBuffer) + 1;
}
// Copy the Email Name if needed
//
ppsz = (TCHAR **) p->ClientInfo.apszStdAttrValues[ENUM_CLIENTATTR_EMAIL_NAME];
if (ppsz != NULL)
{
plci->uOffsetEMailName = (ULONG)((ULONG_PTR) pszStringBuffer - (ULONG_PTR) plci);
My_lstrcpy (pszStringBuffer, *ppsz);
pszStringBuffer += lstrlen (pszStringBuffer) + 1;
}
// Copy the City Name if needed
//
ppsz = (TCHAR **) p->ClientInfo.apszStdAttrValues[ENUM_CLIENTATTR_CITY_NAME];
if (ppsz != NULL)
{
plci->uOffsetCityName = (ULONG)((ULONG_PTR) pszStringBuffer - (ULONG_PTR) plci);
My_lstrcpy (pszStringBuffer, *ppsz);
pszStringBuffer += lstrlen (pszStringBuffer) + 1;
}
// Copy the Country Name if needed
//
ppsz = (TCHAR **) p->ClientInfo.apszStdAttrValues[ENUM_CLIENTATTR_C];
if (ppsz != NULL)
{
plci->uOffsetCountryName = (ULONG)((ULONG_PTR) pszStringBuffer - (ULONG_PTR) plci);
My_lstrcpy (pszStringBuffer, *ppsz);
pszStringBuffer += lstrlen (pszStringBuffer) + 1;
}
// Copy the Comment Name if needed
//
ppsz = (TCHAR **) p->ClientInfo.apszStdAttrValues[ENUM_CLIENTATTR_COMMENT];
if (ppsz != NULL)
{
plci->uOffsetComment = (ULONG)((ULONG_PTR) pszStringBuffer - (ULONG_PTR) plci);
My_lstrcpy (pszStringBuffer, *ppsz);
pszStringBuffer += lstrlen (pszStringBuffer) + 1;
}
// Copy the IP Address if needed
//
ppsz = (TCHAR **) p->ClientInfo.apszStdAttrValues[ENUM_CLIENTATTR_IP_ADDRESS];
if (ppsz != NULL)
{
plci->uOffsetIPAddress = (ULONG)((ULONG_PTR) pszStringBuffer - (ULONG_PTR) plci);
GetIPAddressString (pszStringBuffer, GetStringLong (*ppsz));
pszStringBuffer += lstrlen (pszStringBuffer) + 1;
}
// Copy the Flags if needed
//
ppsz = (TCHAR **) p->ClientInfo.apszStdAttrValues[ENUM_CLIENTATTR_FLAGS];
if (ppsz != NULL)
{
plci->dwFlags = (*ppsz != NULL) ? GetStringLong (*ppsz) :
INVALID_USER_FLAGS;
}
// Copy extended attributes if needed
//
plci->cAttrsReturned = cAttrs = p->Attrs.cMaxAttrs;
plci->uOffsetAttrsReturned = (ULONG)((ULONG_PTR) pszStringBuffer - (ULONG_PTR) plci);
for (j = 0; j < cAttrs; j++)
{
// Extended attribute name
//
My_lstrcpy (pszStringBuffer, IlsSkipAnyAttrNamePrefix (
(const TCHAR *) p->Attrs.aPairs[j].pszName));
pszStringBuffer += lstrlen (pszStringBuffer) + 1;
// Extended attribute value
//
ppsz = (TCHAR **) p->Attrs.aPairs[j].pszValue;
if (ppsz != NULL)
{
My_lstrcpy (pszStringBuffer, *ppsz);
}
else
{
ASSERT(FALSE);
}
pszStringBuffer += lstrlen (pszStringBuffer) + 1;
} // for j
} // for i
}
#ifdef ENABLE_MEETING_PLACE
VOID BuildEnumMtgInfos (
LDAP_ENUM *pEnum,
ENUM_LIST *pEnumList )
{
MyAssert (pEnum != NULL);
MyAssert (pEnumList != NULL);
ULONG i, j;
ULONG cEntries = pEnumList->cItems;
ULONG cbEntrySize = pEnumList->cbEntrySize;
LDAP_MEETINFO *plmi = (LDAP_MEETINFO *) (pEnum + 1);
TCHAR *pszStringBuffer = (TCHAR *) (plmi + cEntries);
TCHAR **ppsz;
MTG_INFO_ATTRS *p;
ULONG cAttrs;
// Loop through all entries
//
for (i = 0; i < cEntries; i++, plmi++)
{
// Get to the cache structure
//
p = (MTG_INFO_ATTRS *) (&(pEnumList->bData[0]) + i * cbEntrySize);
// Set the size of LDAP_MEETINFO
//
plmi->uSize = sizeof (*plmi);
// Copy the Meeting Name if needed
//
ppsz = (TCHAR **) p->MtgInfo.apszStdAttrValues[ENUM_MTGATTR_CN];
if (ppsz != NULL)
{
plmi->uOffsetMeetingPlaceID = (ULONG) pszStringBuffer - (ULONG) plmi;
My_lstrcpy (pszStringBuffer, *ppsz);
pszStringBuffer += lstrlen (pszStringBuffer) + 1;
}
// Copy the Meeting Type if needed
//
ppsz = (TCHAR **) p->MtgInfo.apszStdAttrValues[ENUM_MTGATTR_MTG_TYPE];
if (ppsz != NULL)
{
plmi->lMeetingPlaceType = (*ppsz != NULL) ? GetStringLong (*ppsz) :
INVALID_MEETING_TYPE;
}
// Copy the Attendee Type if needed
//
ppsz = (TCHAR **) p->MtgInfo.apszStdAttrValues[ENUM_MTGATTR_MEMBER_TYPE];
if (ppsz != NULL)
{
plmi->lAttendeeType = (*ppsz != NULL) ? GetStringLong (*ppsz) :
INVALID_ATTENDEE_TYPE;
}
// Copy the Description if needed
//
ppsz = (TCHAR **) p->MtgInfo.apszStdAttrValues[ENUM_MTGATTR_DESCRIPTION];
if (ppsz != NULL)
{
plmi->uOffsetDescription = (ULONG) pszStringBuffer - (ULONG) plmi;
My_lstrcpy (pszStringBuffer, *ppsz);
pszStringBuffer += lstrlen (pszStringBuffer) + 1;
}
// Copy the Host Name if needed
//
ppsz = (TCHAR **) p->MtgInfo.apszStdAttrValues[ENUM_MTGATTR_HOST_NAME];
if (ppsz != NULL)
{
plmi->uOffsetHostName = (ULONG) pszStringBuffer - (ULONG) plmi;
My_lstrcpy (pszStringBuffer, *ppsz);
pszStringBuffer += lstrlen (pszStringBuffer) + 1;
}
// Copy the Host IP Address if needed
//
ppsz = (TCHAR **) p->MtgInfo.apszStdAttrValues[ENUM_MTGATTR_IP_ADDRESS];
if (ppsz != NULL)
{
plmi->uOffsetHostIPAddress = (ULONG) pszStringBuffer - (ULONG) plmi;
GetIPAddressString (pszStringBuffer, GetStringLong (*ppsz));
pszStringBuffer += lstrlen (pszStringBuffer) + 1;
}
// Copy extended attributes if needed
//
plmi->cAttrsReturned = cAttrs = p->Attrs.cMaxAttrs;
plmi->uOffsetAttrsReturned = (ULONG) pszStringBuffer - (ULONG) plmi;
for (j = 0; j < cAttrs; j++)
{
// Extended attribute name
//
My_lstrcpy (pszStringBuffer, IlsSkipAnyAttrNamePrefix (
(const TCHAR *) p->Attrs.aPairs[j].pszName));
pszStringBuffer += lstrlen (pszStringBuffer) + 1;
// Extended attribute value
//
ppsz = (TCHAR **) p->Attrs.aPairs[j].pszValue;
My_lstrcpy (pszStringBuffer, *ppsz);
pszStringBuffer += lstrlen (pszStringBuffer) + 1;
} // for j
} // for i
}
#endif // ENABLE_MEETING_PLACE
VOID TotalSizeEnumObjectNames (
ULONG *pcbTotalSize,
ULONG cEntries,
TCHAR **appszObjectNames[] )
{
ULONG i, cbThisSize;
TCHAR **ppsz;
// Loop through all the entries and compute the total size
//
for (i = 0; i < cEntries; i++)
{
ppsz = appszObjectNames[i];
// Calcualte the attribute string length
//
cbThisSize = 1;
if (ppsz != NULL && *ppsz != NULL)
cbThisSize += My_lstrlen (*ppsz);
// Convert string length to string size
//
cbThisSize *= sizeof (TCHAR);
// Add up this entry size
//
// lonchanc: BUGS BUGS the size is wrong. need to figure out the exact size
*pcbTotalSize += sizeof (LDAP_CLIENTINFO) + cbThisSize;
}
}
VOID SizeEnumClientInfos (
ULONG *pcbTotalSize,
CLIENT_INFO_ATTRS *pcia )
{
ULONG i, cbThisSize;
TCHAR **ppsz;
// Add up user info header
//
*pcbTotalSize += sizeof (LDAP_CLIENTINFO);
// Add up the total size for standard attributes
//
for (i = 0; i < COUNT_ENUM_DIR_CLIENT_INFO; i++)
{
// Get the attribute value
//
ppsz = (TCHAR **) pcia->ClientInfo.apszStdAttrValues[i];
// Calcualte the attribute string length
//
cbThisSize = 1;
if (ppsz != NULL && *ppsz != NULL)
cbThisSize += My_lstrlen (*ppsz);
// Compensate the string length if it is ip address
//
if (i == ENUM_CLIENTATTR_IP_ADDRESS)
cbThisSize += 16;
// Convert string length to string size
//
cbThisSize *= sizeof (TCHAR);
// Add up this entry size
//
*pcbTotalSize += cbThisSize;
}
// Add up the total size for extended attributes
//
for (i = 0; i < pcia->Attrs.cMaxAttrs; i++)
{
// Get the extended attribute value
//
ppsz = (TCHAR **) pcia->Attrs.aPairs[i].pszValue;
// Calcualte the attribute string length
//
cbThisSize = 1;
if (ppsz != NULL && *ppsz != NULL)
cbThisSize += My_lstrlen (*ppsz);
// Get the extended attribute name
//
cbThisSize += lstrlen (IlsSkipAnyAttrNamePrefix ((const TCHAR *)
pcia->Attrs.aPairs[i].pszName)) + 1;
// Convert string length to string size
//
cbThisSize *= sizeof (TCHAR);
// Add up this entry size
//
*pcbTotalSize += cbThisSize;
}
}
#ifdef ENABLE_MEETING_PLACE
VOID SizeEnumMtgInfos (
ULONG *pcbTotalSize,
MTG_INFO_ATTRS *pmia )
{
ULONG i, cbThisSize;
TCHAR **ppsz;
// Add up meeting info header
//
*pcbTotalSize += sizeof (LDAP_MEETINFO);
// Add up the total size for standard attributes
//
for (i = 0; i < COUNT_ENUM_DIRMTGINFO; i++)
{
// Get the standard attribute value
//
ppsz = (TCHAR **) pmia->MtgInfo.apszStdAttrValues[i];
// Calcualte the attribute string length
//
cbThisSize = 1;
if (ppsz != NULL && *ppsz != NULL)
cbThisSize += My_lstrlen (*ppsz);
// Compensate the string length if it is ip address
//
if (i == ENUM_MTGATTR_IP_ADDRESS)
cbThisSize += 16;
// Convert string length to string size
//
cbThisSize *= sizeof (TCHAR);
// Add up this entry size
//
*pcbTotalSize += cbThisSize;
}
// Add up the total size for extended attributes
//
for (i = 0; i < pmia->Attrs.cMaxAttrs; i++)
{
// Get the extended attribute value
//
ppsz = (TCHAR **) pmia->Attrs.aPairs[i].pszValue;
// Calcualte the attribute string length
//
cbThisSize = 1;
if (ppsz != NULL && *ppsz != NULL)
cbThisSize += My_lstrlen (*ppsz);
// Get the extended attribute name
//
cbThisSize += lstrlen (IlsSkipAnyAttrNamePrefix ((const TCHAR *)
pmia->Attrs.aPairs[i].pszName)) + 1;
// Convert string length to string size
//
cbThisSize *= sizeof (TCHAR);
// Add up this entry size
//
*pcbTotalSize += cbThisSize;
}
}
#endif // ENABLE_MEETING_PLACE
/* =========== RESOLVE ============ */
typedef HRESULT (INFO_HANDLER) ( VOID *, const TCHAR *, const TCHAR ** );
extern HRESULT CacheResolveClientInfoAttr ( VOID *, const TCHAR *, const TCHAR ** );
extern HRESULT CacheResolveProtInfoAttr ( VOID *, const TCHAR *, const TCHAR ** );
extern HRESULT CacheResolveMtgInfoAttr ( VOID *, const TCHAR *, const TCHAR ** );
BOOL
NotifyResolveX (
HRESULT hrServer,
SP_CResponse *pItem,
VOID *pInfo,
INFO_HANDLER *pHandler )
{
MyAssert (pItem != NULL);
MyAssert (pInfo != NULL);
MyAssert (pHandler != NULL);
// Get the ldap result
//
LDAPMessage *pLdapMsg = pItem->GetResult ();
MyAssert (pLdapMsg != NULL);
if (pLdapMsg == NULL)
{
MyAssert (FALSE);
hrServer = ILS_E_POINTER;
goto MyExit;
}
// Get ld
//
LDAP *ld;
ld = pItem->GetLd ();
if (ld == NULL)
{
MyAssert (FALSE);
hrServer = ILS_E_HANDLE;
goto MyExit;
}
// Get the first entry that we care only
//
LDAPMessage *pEntry;
pEntry = ldap_first_entry (ld, pLdapMsg);
if (pEntry == NULL)
{
MyAssert (FALSE);
hrServer = ILS_E_MEMORY;
goto MyExit;
}
// Initialize wldap32.dll context
//
struct berelement *pContext;
pContext = NULL;
// Examine the first attribute
//
TCHAR *pszAttrName;
pszAttrName = ldap_first_attribute (ld, pEntry, &pContext);
if (pszAttrName == NULL)
{
MyAssert (FALSE);
hrServer = ILS_E_MEMORY;
goto MyExit;
}
TCHAR **ppszAttrVal;
ppszAttrVal = ldap_get_values (ld, pEntry, pszAttrName);
if (ppszAttrVal == NULL)
{
MyAssert (FALSE);
hrServer = ILS_E_MEMORY;
goto MyExit;
}
// Cache this attribute name (if needed) and value
//
HRESULT hr;
hr = (*pHandler) (pInfo, pszAttrName,(const TCHAR **) ppszAttrVal);
ldap_value_free (ppszAttrVal);
if (hr != S_OK)
{
hrServer = hr;
goto MyExit;
}
// Step through the other attributes
//
while ((pszAttrName = ldap_next_attribute (ld, pEntry, pContext))
!= NULL)
{
ppszAttrVal = ldap_get_values (ld, pEntry, pszAttrName);
if (ppszAttrVal == NULL)
{
MyAssert (FALSE);
hrServer = ILS_E_MEMORY;
goto MyExit;
}
// Cache the other attribute names (if needed) and values
//
hr = (*pHandler) (pInfo, pszAttrName, (const TCHAR **) ppszAttrVal);
ldap_value_free (ppszAttrVal);
if (hr != S_OK)
{
hrServer = hr;
goto MyExit;
}
}
MyAssert (hrServer == S_OK);
MyExit:
return hrServer;
}
BOOL
NotifyResolveClient (
HRESULT hrServer,
SP_CResponse *pItem )
{
MyAssert (pItem != NULL);
ULONG i;
// Get the pending info
//
RESP_INFO *pInfo = pItem->GetRespInfo ();
MyAssert (pInfo != NULL);
// Initialize minimal info
//
LDAP_CLIENTINFO_RES *pClientRes = NULL;
CLIENT_INFO_ATTRS *pcia = NULL;
// If error, simply report the error
//
if (hrServer != S_OK)
goto MyExit;
// Get the ldap result
//
LDAPMessage *pLdapMsg;
pLdapMsg = pItem->GetResult ();
if (pLdapMsg == NULL)
{
MyAssert (FALSE);
goto MyExit;
}
// Get ld
//
LDAP *ld;
ld = pItem->GetLd ();
if (ld == NULL)
{
MyAssert (FALSE);
hrServer = ILS_E_HANDLE;
goto MyExit;
}
// Get the count of attributes
//
ULONG cAttrs;
cAttrs = my_ldap_count_1st_entry_attributes (ld, pLdapMsg);
if (cAttrs == 0)
{
hrServer = ILS_E_NO_MORE;
goto MyExit;
}
// Allocate result set holder
//
pcia = (CLIENT_INFO_ATTRS *) MemAlloc (
sizeof (CLIENT_INFO_ATTRS) +
cAttrs * sizeof (ATTR_PAIR));
if (pcia == NULL)
{
hrServer = ILS_E_MEMORY;
goto MyExit;
}
// Initialize result set holder
//
pcia->Attrs.cMaxAttrs = cAttrs;
// Cache resolve set
//
hrServer = NotifyResolveX ( hrServer,
pItem,
pcia,
CacheResolveClientInfoAttr);
if (hrServer != S_OK)
{
goto MyExit;
}
// Initialize the total size
//
ULONG cbTotalSize, cbThisSize;
cbTotalSize = sizeof (LDAP_CLIENTINFO_RES);
// Loop through all attributes in order to compute the total size
//
for (i = 0; i < COUNT_ENUM_RES_CLIENT_INFO; i++)
{
if (pcia->ClientInfo.apszStdAttrValues[i] != NULL)
{
// Get the string length
//
cbThisSize = My_lstrlen (pcia->ClientInfo.apszStdAttrValues[i]) + 1;
// Compensate for the ip address
//
if (i == ENUM_CLIENTATTR_IP_ADDRESS)
cbThisSize += 16;
// Convert string length to string size
//
cbThisSize *= sizeof (TCHAR);
// Add up to the total size
//
cbTotalSize += cbThisSize;
}
}
// Loop through extended attributes
//
for (i = 0; i < pcia->Attrs.cCurrAttrs; i++)
{
cbThisSize = My_lstrlen (pcia->Attrs.aPairs[i].pszName) + 1;
cbThisSize += My_lstrlen (pcia->Attrs.aPairs[i].pszValue) + 1;
cbThisSize *= sizeof (TCHAR);
cbTotalSize += cbThisSize;
}
// Allocate LDAP_USERINFO_RES structure
//
pClientRes = (LDAP_CLIENTINFO_RES *) MemAlloc (cbTotalSize);
if (pClientRes == NULL)
{
MyAssert (FALSE); // we are in deep trouble here
hrServer = ILS_E_MEMORY;
goto MyExit;
}
// Fill in common fields
//
pClientRes->uSize = sizeof (*pClientRes);
pClientRes->hResult = hrServer;
pClientRes->lci.uSize = sizeof (pClientRes->lci);
// Prepare to copy strings
//
TCHAR *pszDst, *pszSrc;
pszDst = (TCHAR *) (pClientRes + 1);
// Copy user object's standard attributes
//
pszSrc = pcia->ClientInfo.apszStdAttrValues[ENUM_CLIENTATTR_CN];
if (pszSrc != NULL)
{
pClientRes->lci.uOffsetCN = (ULONG)((ULONG_PTR) pszDst - (ULONG_PTR) &(pClientRes->lci));
My_lstrcpy (pszDst, pszSrc);
pszDst += lstrlen (pszDst) + 1;
}
pszSrc = pcia->ClientInfo.apszStdAttrValues[ENUM_CLIENTATTR_FIRST_NAME];
if (pszSrc != NULL)
{
pClientRes->lci.uOffsetFirstName = (ULONG)((ULONG_PTR) pszDst - (ULONG_PTR) &(pClientRes->lci));
My_lstrcpy (pszDst, pszSrc);
pszDst += lstrlen (pszDst) + 1;
}
pszSrc = pcia->ClientInfo.apszStdAttrValues[ENUM_CLIENTATTR_LAST_NAME];
if (pszSrc != NULL)
{
pClientRes->lci.uOffsetLastName = (ULONG)((ULONG_PTR) pszDst - (ULONG_PTR) &(pClientRes->lci));
My_lstrcpy (pszDst, pszSrc);
pszDst += lstrlen (pszDst) + 1;
}
pszSrc = pcia->ClientInfo.apszStdAttrValues[ENUM_CLIENTATTR_EMAIL_NAME];
if (pszSrc != NULL)
{
pClientRes->lci.uOffsetEMailName = (ULONG)((ULONG_PTR) pszDst - (ULONG_PTR) &(pClientRes->lci));
My_lstrcpy (pszDst, pszSrc);
pszDst += lstrlen (pszDst) + 1;
}
pszSrc = pcia->ClientInfo.apszStdAttrValues[ENUM_CLIENTATTR_CITY_NAME];
if (pszSrc != NULL)
{
pClientRes->lci.uOffsetCityName = (ULONG)((ULONG_PTR) pszDst - (ULONG_PTR) &(pClientRes->lci));
My_lstrcpy (pszDst, pszSrc);
pszDst += lstrlen (pszDst) + 1;
}
pszSrc = pcia->ClientInfo.apszStdAttrValues[ENUM_CLIENTATTR_C];
if (pszSrc != NULL)
{
pClientRes->lci.uOffsetCountryName = (ULONG)((ULONG_PTR) pszDst - (ULONG_PTR) &(pClientRes->lci));
My_lstrcpy (pszDst, pszSrc);
pszDst += lstrlen (pszDst) + 1;
}
pszSrc = pcia->ClientInfo.apszStdAttrValues[ENUM_CLIENTATTR_COMMENT];
if (pszSrc != NULL)
{
pClientRes->lci.uOffsetComment = (ULONG)((ULONG_PTR) pszDst - (ULONG_PTR) &(pClientRes->lci));
My_lstrcpy (pszDst, pszSrc);
pszDst += lstrlen (pszDst) + 1;
}
pszSrc = pcia->ClientInfo.apszStdAttrValues[ENUM_CLIENTATTR_IP_ADDRESS];
if (pszSrc != NULL)
{
pClientRes->lci.uOffsetIPAddress = (ULONG)((ULONG_PTR) pszDst - (ULONG_PTR) &(pClientRes->lci));
GetIPAddressString (pszDst, GetStringLong (pszSrc));
pszDst += lstrlen (pszDst) + 1;
}
pszSrc = pcia->ClientInfo.apszStdAttrValues[ENUM_CLIENTATTR_FLAGS];
if (pszSrc != NULL)
{
pClientRes->lci.dwFlags = (pszSrc != NULL)? GetStringLong (pszSrc) :
INVALID_USER_FLAGS;
}
// Copy app object's standard attributes
//
pszSrc = pcia->ClientInfo.apszStdAttrValues[ENUM_CLIENTATTR_APP_NAME];
if (pszSrc != NULL)
{
pClientRes->lci.uOffsetAppName = (ULONG)((ULONG_PTR) pszDst - (ULONG_PTR) &(pClientRes->lci));
My_lstrcpy (pszDst, pszSrc);
pszDst += lstrlen (pszDst) + 1;
}
pszSrc = pcia->ClientInfo.apszStdAttrValues[ENUM_CLIENTATTR_APP_MIME_TYPE];
if (pszSrc != NULL)
{
pClientRes->lci.uOffsetAppMimeType = (ULONG)((ULONG_PTR) pszDst - (ULONG_PTR) &(pClientRes->lci));
My_lstrcpy (pszDst, pszSrc);
pszDst += lstrlen (pszDst) + 1;
}
pszSrc = pcia->ClientInfo.apszStdAttrValues[ENUM_CLIENTATTR_APP_GUID];
if (MyIsGoodString (pszSrc))
{
GetStringGuid (pszSrc, &(pClientRes->lci.AppGuid));
}
else
{
ZeroMemory (&(pClientRes->lci.AppGuid), sizeof (pClientRes->lci.AppGuid));
}
// Copy app object's extended attributes
//
pClientRes->lci.cAttrsReturned = pcia->Attrs.cCurrAttrs;
if (pClientRes->lci.cAttrsReturned > 0)
{
pClientRes->lci.uOffsetAttrsReturned = (ULONG)((ULONG_PTR) pszDst - (ULONG_PTR) &(pClientRes->lci));
for (i = 0; i < pcia->Attrs.cCurrAttrs; i++)
{
My_lstrcpy (pszDst, pcia->Attrs.aPairs[i].pszName);
pszDst += lstrlen (pszDst) + 1;
My_lstrcpy (pszDst, pcia->Attrs.aPairs[i].pszValue);
pszDst += lstrlen (pszDst) + 1;
}
}
MyAssert (hrServer == S_OK);
MyExit:
// Free temporary result set holder
//
if (pcia != NULL)
{
// Free standard attributes
//
for (INT i = 0; i < COUNT_ENUM_CLIENT_INFO; i++)
{
MemFree (pcia->ClientInfo.apszStdAttrValues[i]);
}
// Free arbitrary attributes
//
for (ULONG j = 0; j < pcia->Attrs.cCurrAttrs; j++)
{
MemFree (pcia->Attrs.aPairs[j].pszName);
MemFree (pcia->Attrs.aPairs[j].pszValue);
}
// Free the holder itself
//
MemFree (pcia);
}
// Clean up the return structure if failure
//
if (hrServer != S_OK)
{
// Make sure we have a return structure
//
if (pClientRes != NULL)
ZeroMemory (pClientRes, sizeof (*pClientRes));
else
pClientRes = (LDAP_CLIENTINFO_RES *) MemAlloc (sizeof (LDAP_CLIENTINFO_RES));
// Fill in the minimal info
//
if (pClientRes != NULL)
{
pClientRes->uSize = sizeof (*pClientRes);
pClientRes->hResult = hrServer;
}
}
// Post a message to the com layer
//
PostMessage (g_hWndNotify, pInfo->uNotifyMsg, pInfo->uRespID, (LPARAM) pClientRes);
// Delete this pending item
//
return TRUE;
}
HRESULT CacheResolveClientInfoAttr (
VOID *pInfo,
const TCHAR *pszAttrName,
const TCHAR **ppszAttrVal )
{
MyAssert (pInfo != NULL);
MyAssert (pszAttrName != NULL);
// Shorthand meeting info pointer
//
CLIENT_INFO_ATTRS *pcia = (CLIENT_INFO_ATTRS *) pInfo;
// See if this attribute is arbitrary?
//
const TCHAR *pszRealAnyName = IlsIsAnyAttrName (pszAttrName);
if (pszRealAnyName != NULL)
{
MyAssert (pcia->Attrs.cCurrAttrs < pcia->Attrs.cMaxAttrs);
// Duplicate the name
//
pcia->Attrs.aPairs[pcia->Attrs.cCurrAttrs].pszName =
My_strdup (pszRealAnyName);
// Duplicate the value
// BUGS: we should avoid duplicate the string here (cf. enum-user-infos)
//
if (ppszAttrVal != NULL)
{
pcia->Attrs.aPairs[pcia->Attrs.cCurrAttrs++].pszValue =
My_strdup (*ppszAttrVal);
}
else
{
// ILS server bug or wldap32.dll bug
//
MyAssert (FALSE);
}
}
else
{
// Loop through all standard attributes
//
for (INT i = 0; i < COUNT_ENUM_RES_CLIENT_INFO; i++)
{
// Figure out what attribute it is
//
if (My_lstrcmpi (c_apszClientStdAttrNames[i], pszAttrName) == 0)
{
// Free the previously allocated value if any
//
MemFree (pcia->ClientInfo.apszStdAttrValues[i]);
// Duplicate the value
// BUGS: we should avoid duplicate the string here (cf. enum-user-infos)
//
if (ppszAttrVal != NULL)
{
pcia->ClientInfo.apszStdAttrValues[i] = DuplicateGoodString (*ppszAttrVal);
}
else
{
// ILS server bug or wldap32.dll bug
//
MyAssert (FALSE);
}
break;
}
}
}
return S_OK;
}
typedef struct
{
PROT_INFO ProtInfo;
TCHAR *pszProtNameToResolve;
BOOL fFindIndex;
LONG nIndex;
}
PROT_INFO_EX;
enum { INVALID_INDEX = -1 };
BOOL NotifyResolveProt ( HRESULT hrServer, SP_CResponse *pItem )
{
MyAssert (pItem != NULL);
// Get the pending info
//
RESP_INFO *pInfo = pItem->GetRespInfo ();
MyAssert (pInfo != NULL);
// Initialize minimal info
//
LDAP_PROTINFO_RES *pProtRes = NULL;
PROT_INFO_EX *ppi = NULL;
// If error, simply report the error
//
if (hrServer != S_OK)
goto MyExit;
// Allocate result holder
//
ppi = (PROT_INFO_EX *) MemAlloc (sizeof (PROT_INFO_EX));
if (ppi == NULL)
{
hrServer = ILS_E_MEMORY;
goto MyExit;
}
// Cache the protocol name to resolve
//
MyAssert (pInfo->pszProtNameToResolve != NULL);
ppi->pszProtNameToResolve = pInfo->pszProtNameToResolve;
ppi->nIndex = INVALID_INDEX;
// Call the common routine to find the index
//
ppi->fFindIndex = TRUE;
hrServer = NotifyResolveX (hrServer, pItem, ppi, CacheResolveProtInfoAttr);
if (hrServer != S_OK)
goto MyExit;
// Check to see if we found the index
//
if (ppi->nIndex == INVALID_INDEX)
{
hrServer = ILS_E_NO_SUCH_OBJECT;
goto MyExit;
}
// Call the common routine AGAIN to save attribute values
//
ppi->fFindIndex = FALSE;
hrServer = NotifyResolveX (hrServer, pItem, ppi, CacheResolveProtInfoAttr);
if (hrServer != S_OK)
goto MyExit;
// Initialize the size
//
ULONG cbTotalSize, cbThisSize;
cbTotalSize = sizeof (LDAP_PROTINFO_RES);
// Loop through standard attrs
//
ULONG i;
for (i = 0; i < COUNT_ENUM_PROTATTR; i++)
{
if (ppi->ProtInfo.apszStdAttrValues[i] != NULL)
{
cbThisSize = My_lstrlen (ppi->ProtInfo.apszStdAttrValues[i]) + 1;
cbThisSize *= sizeof (TCHAR);
cbTotalSize += cbThisSize;
}
}
// Allocate LDAP_PROTINFO_RES structure
//
pProtRes = (LDAP_PROTINFO_RES *) MemAlloc (cbTotalSize);
if (pProtRes == NULL)
{
MyAssert (FALSE); // we are in deep trouble here
hrServer = ILS_E_MEMORY;
goto MyExit;
}
// Fill in fields
//
pProtRes->uSize = sizeof (*pProtRes);
pProtRes->hResult = hrServer;
pProtRes->lpi.uSize = sizeof (pProtRes->lpi);
TCHAR *pszSrc, *pszDst;
pszDst = (TCHAR *) (pProtRes + 1);
// Copy protocol name
//
pszSrc = ppi->ProtInfo.apszStdAttrValues[ENUM_PROTATTR_NAME];
if (pszSrc != NULL)
{
pProtRes->lpi.uOffsetName = (ULONG)((ULONG_PTR) pszDst - (ULONG_PTR) &(pProtRes->lpi));
My_lstrcpy (pszDst, pszSrc);
pszDst += lstrlen (pszDst) + 1;
}
// Copy protocol mime type
//
pszSrc = ppi->ProtInfo.apszStdAttrValues[ENUM_PROTATTR_MIME_TYPE];
if (pszSrc != NULL)
{
pProtRes->lpi.uOffsetMimeType = (ULONG)((ULONG_PTR) pszDst - (ULONG_PTR) &(pProtRes->lpi));
My_lstrcpy (pszDst, pszSrc);
pszDst += lstrlen (pszDst) + 1;
}
// Copy protocol prot number
//
pszSrc = ppi->ProtInfo.apszStdAttrValues[ENUM_PROTATTR_PORT_NUMBER];
if (pszSrc != NULL)
{
pProtRes->lpi.uPortNumber = GetStringLong (pszSrc);
}
MyAssert (hrServer == S_OK);
MyExit:
// Free temporary app result holder
//
if (ppi != NULL)
{
for (INT i = 0; i < COUNT_ENUM_PROTATTR; i++)
{
MemFree (ppi->ProtInfo.apszStdAttrValues[i]);
}
MemFree (ppi);
}
// Clean up the return structure if failure
//
if (hrServer != S_OK)
{
// Make sure we have a valid returned structure
//
if (pProtRes != NULL)
ZeroMemory (pProtRes, sizeof (*pProtRes));
else
pProtRes = (LDAP_PROTINFO_RES *) MemAlloc (sizeof (LDAP_PROTINFO_RES));
// Fill in the minimal info
//
if (pProtRes != NULL)
{
pProtRes->uSize = sizeof (*pProtRes);
pProtRes->hResult = hrServer;
}
}
// Post the result to the com layer
//
PostMessage (g_hWndNotify, pInfo->uNotifyMsg, pInfo->uRespID, (LPARAM) pProtRes);
// Destroy this pending item
//
return TRUE;
}
HRESULT CacheResolveProtInfoAttr (
VOID *pInfo,
const TCHAR *pszAttrName,
const TCHAR **ppszAttrVal )
{
MyAssert (pInfo != NULL);
MyAssert (pszAttrName != NULL);
// Shorthand prot info pointer
//
PROT_INFO_EX *ppi = (PROT_INFO_EX *) pInfo;
// Are we trying to find the index of the protocol to resolve?
//
if (ppi->fFindIndex)
{
// If we already located the index, then simply return
//
if (ppi->nIndex == INVALID_INDEX)
{
// Looking for "sprotid"
//
if (My_lstrcmpi (STR_PROT_NAME, pszAttrName) == 0)
{
// Get to the protocol name attribute
//
if (ppszAttrVal != NULL)
{
TCHAR *pszVal;
for (LONG nIndex = 0;
(pszVal = (TCHAR *) ppszAttrVal[nIndex]) != NULL;
nIndex++)
{
if (My_lstrcmpi (ppi->pszProtNameToResolve, pszVal) == 0)
{
// Locate the same protocol name, remember the index
//
ppi->nIndex = nIndex;
break;
// return S_OK; // we should be able to return from here
}
}
}
else
{
// ILS server bug or wldap32.dll bug
//
MyAssert (FALSE);
}
}
}
}
else
{
// Loop through all standard attributes
//
for (INT i = 0; i < COUNT_ENUM_PROTATTR; i++)
{
// Figure out what attribute it is
//
if (My_lstrcmpi (c_apszProtStdAttrNames[i], pszAttrName) == 0)
{
// Free the previously allocated value if any
//
MemFree (ppi->ProtInfo.apszStdAttrValues[i]);
// Duplicate the value
// BUGS: we should avoid duplicate the string here (cf. enum-user-infos)
//
if (ppszAttrVal != NULL)
{
// Make sure that we do not fault when the ILS server or wldap32.dll has a bug
//
for (LONG nIndex = 0; nIndex <= ppi->nIndex; nIndex++)
{
if (ppszAttrVal[nIndex] == NULL)
{
// ILS server bug
//
MyAssert (FALSE);
return S_OK;
}
}
// Duplicate the attribute value
//
ppi->ProtInfo.apszStdAttrValues[i] = My_strdup (ppszAttrVal[ppi->nIndex]);
}
else
{
// ILS server bug or wldap32.dll bug
//
MyAssert (FALSE);
}
break;
}
}
}
return S_OK;
}
#ifdef ENABLE_MEETING_PLACE
BOOL NotifyResolveMtg ( HRESULT hrServer, SP_CResponse *pItem )
{
MyAssert (pItem != NULL);
// Get pending info
//
RESP_INFO *pInfo = pItem->GetRespInfo ();
MyAssert (pInfo != NULL);
// Initialize minimal return info
//
LDAP_MEETINFO_RES *pMtgRes = NULL;
MTG_INFO_ATTRS *pmia = NULL;
// If error, simply report the error
//
if (hrServer != S_OK)
goto MyExit;
// Get the ldap result
//
LDAPMessage *pLdapMsg;
pLdapMsg = pItem->GetResult ();
if (pLdapMsg == NULL)
{
MyAssert (FALSE);
goto MyExit;
}
// Get ld
//
LDAP *ld;
ld = pItem->GetLd ();
if (ld == NULL)
{
MyAssert (FALSE);
hrServer = ILS_E_HANDLE;
goto MyExit;
}
// Get the count of attributes
//
ULONG cAttrs;
cAttrs = my_ldap_count_1st_entry_attributes (ld, pLdapMsg);
if (cAttrs == 0)
{
hrServer = ILS_E_NO_MORE;
goto MyExit;
}
// Allocate result set holder
//
pmia = (MTG_INFO_ATTRS *) MemAlloc (
sizeof (MTG_INFO_ATTRS) +
cAttrs * sizeof (ATTR_PAIR));
if (pmia == NULL)
{
hrServer = ILS_E_MEMORY;
goto MyExit;
}
// Initialize result set holder
//
pmia->Attrs.cMaxAttrs = cAttrs;
// Cache resolve set
//
hrServer = NotifyResolveX ( hrServer,
pItem,
pmia,
CacheResolveMtgInfoAttr);
if (hrServer != S_OK)
goto MyExit;
// Initialize the size
//
ULONG cbTotalSize, cbThisSize;
cbTotalSize = sizeof (LDAP_MEETINFO_RES);
// Loop through standard attrs to calculate the total size
//
ULONG i;
for (i = 0; i < COUNT_ENUM_MTGATTR; i++)
{
if (pmia->MtgInfo.apszStdAttrValues[i] != NULL)
{
// Compute the string length
//
cbThisSize = My_lstrlen (pmia->MtgInfo.apszStdAttrValues[i]) + 1;
// Compensate the string length if it is ip address
//
if (i == ENUM_MTGATTR_IP_ADDRESS)
cbThisSize += 16;
// Convert the string length to string size
//
cbThisSize *= sizeof (TCHAR);
// Add up to the total size
//
cbTotalSize += cbThisSize;
}
}
// Loop through arbitrary attrs to calculate the total size
//
for (i = 0; i < pmia->Attrs.cCurrAttrs; i++)
{
cbThisSize = My_lstrlen (pmia->Attrs.aPairs[i].pszName) + 1;
cbThisSize += My_lstrlen (pmia->Attrs.aPairs[i].pszValue) + 1;
cbThisSize *= sizeof (TCHAR);
cbTotalSize += cbThisSize;
}
// Allocate LDAP_MTGINFO_RES structure
//
pMtgRes = (LDAP_MEETINFO_RES *) MemAlloc (cbTotalSize);
if (pMtgRes == NULL)
{
MyAssert (FALSE); // we are in deep trouble here
hrServer = ILS_E_MEMORY;
goto MyExit;
}
// Fill in common fields
//
pMtgRes->uSize = sizeof (*pMtgRes);
pMtgRes->hResult = hrServer;
pMtgRes->lmi.uSize = sizeof (pMtgRes->lmi);
TCHAR *pszSrc, *pszDst;
pszDst = (TCHAR *) (pMtgRes + 1);
// Copy Meeting Name if needed
//
pszSrc = pmia->MtgInfo.apszStdAttrValues[ENUM_MTGATTR_CN];
if (pszSrc != NULL)
{
pMtgRes->lmi.uOffsetMeetingPlaceID = (ULONG) pszDst - (ULONG) &(pMtgRes->lmi);
My_lstrcpy (pszDst, pszSrc);
pszDst += lstrlen (pszDst) + 1;
}
// Copy Meeting Type if needed
//
pszSrc = pmia->MtgInfo.apszStdAttrValues[ENUM_MTGATTR_MTG_TYPE];
if (pszSrc != NULL)
{
pMtgRes->lmi.lMeetingPlaceType = (pszSrc != NULL) ? GetStringLong (pszSrc) :
INVALID_MEETING_TYPE;
}
// Copy Attendee Type if needed
//
pszSrc = pmia->MtgInfo.apszStdAttrValues[ENUM_MTGATTR_MEMBER_TYPE];
if (pszSrc != NULL)
{
pMtgRes->lmi.lAttendeeType = (pszSrc != NULL) ? GetStringLong (pszSrc) :
INVALID_ATTENDEE_TYPE;
}
// Copy Description if needed
//
pszSrc = pmia->MtgInfo.apszStdAttrValues[ENUM_MTGATTR_DESCRIPTION];
if (pszSrc != NULL)
{
pMtgRes->lmi.uOffsetDescription = (ULONG) pszDst - (ULONG) &(pMtgRes->lmi);
My_lstrcpy (pszDst, pszSrc);
pszDst += lstrlen (pszDst) + 1;
}
// Copy Host Name if needed
//
pszSrc = pmia->MtgInfo.apszStdAttrValues[ENUM_MTGATTR_HOST_NAME];
if (pszSrc != NULL)
{
pMtgRes->lmi.uOffsetHostName = (ULONG) pszDst - (ULONG) &(pMtgRes->lmi);
My_lstrcpy (pszDst, pszSrc);
pszDst += lstrlen (pszDst) + 1;
}
// Copy Host IP Address if needed
//
pszSrc = pmia->MtgInfo.apszStdAttrValues[ENUM_MTGATTR_IP_ADDRESS];
if (pszSrc != NULL)
{
pMtgRes->lmi.uOffsetHostIPAddress = (ULONG) pszDst - (ULONG) &(pMtgRes->lmi);
GetIPAddressString (pszDst, GetStringLong (pszSrc));
pszDst += lstrlen (pszDst) + 1;
}
// Copy extended attributes
//
pMtgRes->lmi.cAttrsReturned = pmia->Attrs.cCurrAttrs;
if (pMtgRes->lmi.cAttrsReturned > 0)
{
pMtgRes->lmi.uOffsetAttrsReturned = (ULONG) pszDst - (ULONG) &(pMtgRes->lmi);
for (i = 0; i < pmia->Attrs.cCurrAttrs; i++)
{
My_lstrcpy (pszDst, pmia->Attrs.aPairs[i].pszName);
pszDst += lstrlen (pszDst) + 1;
My_lstrcpy (pszDst, pmia->Attrs.aPairs[i].pszValue);
pszDst += lstrlen (pszDst) + 1;
}
}
MyAssert (hrServer == S_OK);
MyExit:
// Free temporary result set holder
//
if (pmia != NULL)
{
// Free standard attributes
//
for (INT i = 0; i < COUNT_ENUM_MTGATTR; i++)
{
MemFree (pmia->MtgInfo.apszStdAttrValues[i]);
}
// Free arbitrary attributes
//
for (ULONG j = 0; j < pmia->Attrs.cCurrAttrs; j++)
{
MemFree (pmia->Attrs.aPairs[j].pszName);
MemFree (pmia->Attrs.aPairs[j].pszValue);
}
// Free the holder itself
//
MemFree (pmia);
}
// Clean up the return structure if failure
//
if (hrServer != S_OK)
{
// Make sure we have a return structure
//
if (pMtgRes != NULL)
ZeroMemory (pMtgRes, sizeof (*pMtgRes));
else
pMtgRes = (LDAP_MEETINFO_RES *) MemAlloc (sizeof (LDAP_MEETINFO_RES));
// Fill in the minimal info
//
if (pMtgRes != NULL)
{
pMtgRes->uSize = sizeof (*pMtgRes);
pMtgRes->hResult = hrServer;
}
}
// Post a message to the com layer
//
PostMessage (g_hWndNotify, pInfo->uNotifyMsg, pInfo->uRespID, (LPARAM) pMtgRes);
// Delete this pending item
//
return TRUE;
}
#endif // ENABLE_MEETING_PLACE
#ifdef ENABLE_MEETING_PLACE
HRESULT CacheResolveMtgInfoAttr (
VOID *pInfo,
const TCHAR *pszAttrName,
const TCHAR **ppszAttrVal )
{
MyAssert (pInfo != NULL);
MyAssert (pszAttrName != NULL);
// Shorthand meeting info pointer
//
MTG_INFO_ATTRS *pmia = (MTG_INFO_ATTRS *) pInfo;
// See if this attribute is arbitrary?
//
const TCHAR *pszRealAnyName = IlsIsAnyAttrName (pszAttrName);
if (pszRealAnyName != NULL)
{
MyAssert (pmia->Attrs.cCurrAttrs < pmia->Attrs.cMaxAttrs);
// Duplicate the name
//
pmia->Attrs.aPairs[pmia->Attrs.cCurrAttrs].pszName =
My_strdup (pszRealAnyName);
// Duplicate the value
// BUGS: we should avoid duplicate the string here (cf. enum-user-infos)
//
if (ppszAttrVal != NULL)
{
pmia->Attrs.aPairs[pmia->Attrs.cCurrAttrs++].pszValue =
My_strdup (*ppszAttrVal);
}
else
{
// ILS server bug or wldap32.dll bug
//
MyAssert (FALSE);
}
}
else
{
// Loop through all standard attributes
//
for (INT i = 0; i < COUNT_ENUM_RESMTGINFO; i++)
{
// Figure out what attribute it is
//
if (My_lstrcmpi (c_apszMtgStdAttrNames[i], pszAttrName) == 0)
{
// Free the previously allocated value if any
//
MemFree (pmia->MtgInfo.apszStdAttrValues[i]);
// Duplicate the value
// BUGS: we should avoid duplicate the string here (cf. enum-user-infos)
//
if (ppszAttrVal != NULL)
{
pmia->MtgInfo.apszStdAttrValues[i] = My_strdup (*ppszAttrVal);
}
else
{
// ILS server bug or wldap32.dll bug
//
MyAssert (FALSE);
}
break;
}
}
}
return S_OK;
}
#endif // ENABLE_MEETING_PLACE
VOID FreeStdAttrCache ( TCHAR *apszStdAttrValues[], ULONG cStdAttrs )
{
for (ULONG i = 0; i < cStdAttrs; i++)
{
if (apszStdAttrValues[i] != NULL)
{
ldap_value_free ((TCHAR **) apszStdAttrValues[i]);
}
}
}
VOID FreeAttrPairArrayCache ( ATTR_PAIR aAttrPair[], ULONG cPairs )
{
if (aAttrPair != NULL)
{
for (ULONG j = 0; j < cPairs; j++)
{
if (aAttrPair[j].pszValue != NULL)
{
ldap_value_free ((TCHAR **) aAttrPair[j].pszValue);
}
}
}
}
VOID CacheAnyAttrNamesInAttrPairs (
ULONG cNames,
TCHAR *pszSrcNameList,
ATTR_PAIR aPairs[] )
{
MyAssert (cNames != 0);
MyAssert (pszSrcNameList != NULL);
MyAssert (aPairs != NULL);
// Note that all these extended attribute names are already PREFIXED
//
for (ULONG i = 0; i < cNames; i++)
{
aPairs[i].pszName = pszSrcNameList;
pszSrcNameList += lstrlen (pszSrcNameList) + 1;
}
}