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.
2830 lines
63 KiB
2830 lines
63 KiB
/* ----------------------------------------------------------------------
|
|
|
|
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 = NULL;
|
|
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 && 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 ** );
|
|
|
|
|
|
HRESULT
|
|
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 k = 0;k < COUNT_ENUM_CLIENT_INFO; k++)
|
|
{
|
|
MemFree (pcia->ClientInfo.apszStdAttrValues[k]);
|
|
}
|
|
|
|
// 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 k = 0; k < COUNT_ENUM_PROTATTR; k++)
|
|
{
|
|
MemFree (ppi->ProtInfo.apszStdAttrValues[k]);
|
|
}
|
|
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;
|
|
}
|
|
}
|
|
|
|
|
|
|