/*--------------------------------------------------------------------------- File: ListProfiles.cpp Comments: Helper functions that dynamically load the MAPI library, and enumerate the MAPI profiles on the local machine (for the logged on user) (c) Copyright 1999, Mission Critical Software, Inc., All Rights Reserved Proprietary and confidential to Mission Critical Software, Inc. REVISION LOG ENTRY Revision By: Christy Boles Revised on 03/18/99 11:09:53 --------------------------------------------------------------------------- */ #include "stdafx.h" #include "resource.h" #include "ListProf.h" #include "Common.hpp" #include "Ustring.hpp" #include #include HINSTANCE hMapi = NULL; LPMAPIALLOCATEBUFFER pMAPIAllocateBuffer = NULL; LPMAPIFREEBUFFER pMAPIFreeBuffer = NULL; LPMAPIINITIALIZE pMAPIInitialize = NULL; LPMAPIUNINITIALIZE pMAPIUninitialize = NULL; LPMAPILOGONEX pMAPILogonEx = NULL; LPMAPIADMINPROFILES pMAPIAdminProfiles = NULL; LPFREEPADRLIST pFreePadrlist = NULL; LPFREEPROWS pFreeProws = NULL; LPSCDUPPROPSET pScDupPropset = NULL; LPHRQUERYALLROWS pHrQueryAllRows = NULL; LPULRELEASE pUlRelease = NULL; BOOL bMapiInitialized = FALSE; #define NOT_PT_ERROR(x) ( PROP_TYPE(x.ulPropTag) != PT_ERROR ) BOOL LoadMAPI( IVarSet * pVarSet ) { BOOL success = TRUE; WCHAR errString[1000] = L""; if ( ! hMapi ) { hMapi = LoadLibrary(_T("MAPI32.DLL")); if ( hMapi ) { do { // once (only show one error message) pMAPIAllocateBuffer=(LPMAPIALLOCATEBUFFER)GetProcAddress(hMapi,"MAPIAllocateBuffer"); if ( ! pMAPIAllocateBuffer ) { LoadString(NULL,IDS_NoMAPIAllocateBuffer,errString,DIM(errString)); success = FALSE; break; } pMAPIFreeBuffer = (LPMAPIFREEBUFFER)GetProcAddress(hMapi,"MAPIFreeBuffer"); if ( ! pMAPIFreeBuffer ) { LoadString(NULL,IDS_NoMAPIFreeBuffer,errString,DIM(errString)); success = FALSE; break; } pMAPIInitialize = (LPMAPIINITIALIZE)GetProcAddress(hMapi,"MAPIInitialize"); if ( ! pMAPIInitialize ) { LoadString(NULL,IDS_NoMAPIInitialize,errString,DIM(errString)); success = FALSE; break; } pMAPIUninitialize = (LPMAPIUNINITIALIZE)GetProcAddress(hMapi,"MAPIUninitialize"); if ( ! pMAPIUninitialize ) { LoadString(NULL,IDS_NoMAPIUninitialize,errString,DIM(errString)); success = FALSE; break; } pMAPILogonEx = (LPMAPILOGONEX)GetProcAddress(hMapi,"MAPILogonEx"); if ( ! pMAPILogonEx ) { LoadString(NULL,IDS_NoMAPILogonEx,errString,DIM(errString)); success = FALSE; break; } pMAPIAdminProfiles = (LPMAPIADMINPROFILES)GetProcAddress(hMapi,"MAPIAdminProfiles"); if ( ! pMAPIAdminProfiles ) { LoadString(NULL,IDS_NoMAPIAdminProfiles,errString,DIM(errString)); success = FALSE; break; } pFreePadrlist = (LPFREEPADRLIST)GetProcAddress(hMapi,"FreePadrlist@4"); if ( ! pFreePadrlist ) { LoadString(NULL,IDS_NoFreePadrList,errString,DIM(errString)); success = FALSE; break; } pFreeProws = (LPFREEPROWS)GetProcAddress(hMapi,"FreeProws@4"); if ( ! pFreeProws ) { LoadString(NULL,IDS_NoFreeProws,errString,DIM(errString)); success = FALSE; break; } pScDupPropset = (LPSCDUPPROPSET)GetProcAddress(hMapi,"ScDupPropset@16"); if ( ! pScDupPropset ) { LoadString(NULL,IDS_NoScDupPropset,errString,DIM(errString)); success = FALSE; break; } pHrQueryAllRows = (LPHRQUERYALLROWS)GetProcAddress(hMapi,"HrQueryAllRows@24"); if ( ! pHrQueryAllRows ) { LoadString(NULL,IDS_NoHrQueryAllRows,errString,DIM(errString)); success = FALSE; break; } pUlRelease = (LPULRELEASE)GetProcAddress(hMapi,"UlRelease@4"); if ( ! pUlRelease ) { LoadString(NULL,IDS_NoUlRelease,errString,DIM(errString)); success = FALSE; break; } } while (FALSE); } else { success = FALSE; LoadString(NULL,IDS_NO_MAPI,errString,DIM(errString)); } if ( hMapi && !success ) { ReleaseMAPI(); } } if ( !success ) { if ( pVarSet) { pVarSet->put("McsMapiUtil.ErrorText",errString); } } return (hMapi!=NULL && success); } void ReleaseMAPI() { if ( hMapi ) { if ( bMapiInitialized ) { (*pMAPIUninitialize)(); bMapiInitialized = FALSE; } FreeLibrary(hMapi); hMapi = NULL; pMAPIAllocateBuffer = NULL; pMAPIFreeBuffer = NULL; pMAPIInitialize = NULL; pMAPIUninitialize = NULL; pMAPILogonEx = NULL; pMAPIAdminProfiles = NULL; pFreePadrlist = NULL; pFreeProws = NULL; pScDupPropset = NULL; pHrQueryAllRows = NULL; pUlRelease = NULL; } } HRESULT ListProfiles(IVarSet * pVarSet) { HRESULT hr; LPPROFADMIN prof = NULL; LPMAPITABLE table = NULL; LPSRowSet rows = NULL; if ( ! LoadMAPI(pVarSet) ) { return E_FAIL; } if ( ! bMapiInitialized ) { hr = (*pMAPIInitialize)(NULL); if ( SUCCEEDED(hr) ) { bMapiInitialized = TRUE; } } if ( SUCCEEDED(hr) ) { hr = (*pMAPIAdminProfiles)(0,&prof); } if ( SUCCEEDED(hr) ) { hr = prof->GetProfileTable(0,&table); if ( SUCCEEDED(hr) ) { hr = (*pHrQueryAllRows)(table,NULL,NULL,NULL,0,&rows); if ( SUCCEEDED(hr) ) { for ( UINT i = 0 ; i < rows->cRows ; i ++ ) { if ( PROP_TYPE(rows->aRow[i].lpProps[0].ulPropTag ) == PT_STRING8 ) { WCHAR profile[200]; WCHAR key[200]; safecopy(profile,rows->aRow[i].lpProps[0].Value.lpszA); swprintf(key,L"Profiles.%ld",i); pVarSet->put(key,profile); if ( rows->aRow[i].lpProps[1].Value.b ) { swprintf(key,L"Profiles.%ld.Default",i); pVarSet->put(key,"Yes"); } } } } } } if ( rows ) { (*pFreeProws)(rows); } if ( table ) { table->Release(); } if ( prof ) { prof->Release(); } return hr; } // GPSGuid is pbGlobalProfileSectionGuid (defined in edkmdb.h) in a byte[] format // This is used in GetExchangeServerFromProfile #define GPSGuid { 0x13, 0xDB, 0xB0, 0xC8,0xAA,0x05,0x10,0x1A,0x9B,0xB0,0x00,0xAA,0x00,0x2F,0xC4,0x5A } MAPIUID exchSrvrGuid = { 0xdc, 0xa7, 0x40, 0xc8,0xC0,0x42,0x10,0x1a,0xb4,0xb9,0x08,0x00,0x2b,0x2f,0xe1,0x82 }; HRESULT ProfileGetServer(IVarSet * pVarSet,WCHAR const * profileW, WCHAR * computerName) { HRESULT hr; MAPIUID uid = GPSGuid; LPPROFADMIN prof = NULL; LPSERVICEADMIN admin = NULL; LPPROFSECT ps = NULL; char profile[200]; LPSPropValue pVals = NULL; ULONG ulCount = 0; WCHAR errString[1000] = L""; computerName[0] = 0; safecopy(profile,profileW); if ( ! LoadMAPI(pVarSet) ) { return E_FAIL; } if ( ! bMapiInitialized ) { hr = (*pMAPIInitialize)(NULL); if ( SUCCEEDED(hr) ) { bMapiInitialized = TRUE; } } SizedSPropTagArray(1,prop) = { 1, { PR_PROFILE_HOME_SERVER } }; if ( profile[0] ) { hr = (*pMAPIAdminProfiles)(0,&prof); if ( FAILED(hr) ) { LoadString(NULL,IDS_CannotAccessProfiles,errString,DIM(errString)); goto err_continue; } hr = prof->AdminServices((WCHAR *)profile,NULL,NULL,0,&admin); // profile is ANSI, since MAPI_UNICODE flag not set. if ( FAILED(hr) ) { LoadString(NULL,IDS_IProfAdmin_AdminServices,errString,DIM(errString)); goto err_continue; } hr = admin->OpenProfileSection(&uid,NULL,0,&ps); if ( FAILED(hr) ) { LoadString(NULL,IDS_IServiceAdmin_OpenProfileSection,errString,DIM(errString));; goto err_continue; } hr = ps->GetProps((LPSPropTagArray)&prop,0,&ulCount,&pVals); if ( FAILED(hr) ) { LoadString(NULL,IDS_IProfSect_GetProps,errString,DIM(errString));; goto err_continue; } if ( ulCount && PROP_TYPE(pVals[0].ulPropTag) != PT_ERROR ) { UStrCpy(computerName,pVals[0].Value.lpszA); } else { hr = E_FAIL; LoadString(NULL,IDS_DidntGetProp,errString,DIM(errString));; } } err_continue: if ( pVals ) { (*pMAPIFreeBuffer)(pVals); } if ( prof ) { prof->Release(); } if ( admin ) { admin->Release(); } if ( ps ) { ps->Release(); } if ( FAILED(hr) ) { if ( pVarSet ) { pVarSet->put("McsMapiUtil.ErrorText",errString); } } return hr; } HRESULT ListContainers(WCHAR * profileName,IVarSet * pVarSet) { LPMAPISESSION sess = NULL; HRESULT hr = S_OK; LPABCONT pRootEntry = NULL; // root of AB LPMAPITABLE pRootTable = NULL; // root table LPSRowSet pRootRows = NULL; LPADRBOOK pAdrBook = NULL; ULONG ulObjectType = 0; FLAGS fLogonOptions = MAPI_NO_MAIL | MAPI_EXTENDED | MAPI_NEW_SESSION | MAPI_EXPLICIT_PROFILE; char title[MAX_PATH]; char key[MAX_PATH]; char containerDN[MAX_PATH] = ""; long lVarSetNdx = 0; if ( ! LoadMAPI(pVarSet) ) { return E_FAIL; } if ( ! bMapiInitialized ) { hr = (*pMAPIInitialize)(NULL); if ( SUCCEEDED(hr) ) { bMapiInitialized = TRUE; } } if ( SUCCEEDED(hr) ) { hr = (*pMAPILogonEx)(0,profileName,NULL, fLogonOptions | MAPI_UNICODE, &sess); if ( SUCCEEDED(hr) ) { SizedSPropTagArray(4, rgPropTags) = { 4, { PR_ENTRYID, PR_DISPLAY_NAME_A, PR_DEPTH, PR_AB_PROVIDER_ID } }; hr = sess->OpenAddressBook(0, NULL, AB_NO_DIALOG , &pAdrBook); // TODO: error messages for these if ( SUCCEEDED(hr) ) { // Open the root entry. hr = pAdrBook->OpenEntry(0, NULL, NULL, 0, &ulObjectType, (LPUNKNOWN*)&pRootEntry); } // Get its hierarchical table. if ( SUCCEEDED(hr) ) { hr = pRootEntry->GetHierarchyTable( CONVENIENT_DEPTH, &pRootTable); } if ( SUCCEEDED(hr) ) { // Get a list of all rows. hr = (*pHrQueryAllRows)(pRootTable, (LPSPropTagArray)&rgPropTags, NULL, NULL, 0, &pRootRows); } long lStartRow = -1; // Current start point for search. BOOL bAborted = FALSE; // Set TRUE if we punt due to mismatch. long lDepth; // Current depth of search. for (lDepth = 0; (lDepth < 1) && !bAborted; ++lDepth) { ++lStartRow; for (ULONG ulRow = (ULONG)lStartRow; ulRow < pRootRows->cRows; ++ulRow) { // Only display Exchange server containers if ( IsEqualMAPIUID(&exchSrvrGuid,pRootRows->aRow[ulRow].lpProps[3].Value.bin.lpb) ) { long lRowDepth = pRootRows->aRow[ulRow].lpProps[2].Value.l; if ( PROP_TYPE(pRootRows->aRow[ulRow].lpProps[1].ulPropTag) == PT_STRING8 ) { sprintf(title,"%s",pRootRows->aRow[ulRow].lpProps[1].Value.lpszA); sprintf(key,"Container.%ld",lVarSetNdx); pVarSet->put(key,title); sprintf(key,"Container.%ld.Depth",lVarSetNdx); pVarSet->put(key,lRowDepth); // Try to get the distinguished name, so that we can uniquely identify this container later LPSPropValue props = NULL; LPABCONT pEntry = NULL; ULONG ulCount; HRESULT hr2 = S_OK; ULONG ulObjectType; SizedSPropTagArray(2, rgPT2) = { 2, { PR_DISPLAY_NAME_A, PR_EMS_AB_OBJ_DIST_NAME_A } }; if ( NOT_PT_ERROR(pRootRows->aRow[ulRow].lpProps[0]) ) { hr2 = pAdrBook->OpenEntry(pRootRows->aRow[ulRow].lpProps[0].Value.bin.cb, (LPENTRYID)pRootRows->aRow[ulRow].lpProps[0].Value.bin.lpb, NULL, 0, &ulObjectType, (LPUNKNOWN *)&pEntry); } else { hr2 = E_FAIL; } if ( SUCCEEDED(hr2) ) { hr2 = pEntry->GetProps((LPSPropTagArray)&rgPT2,0,&ulCount,&props); } if ( SUCCEEDED(hr2) ) { if ( ulCount && NOT_PT_ERROR(props[1]) ) { UStrCpy(containerDN,props[1].Value.lpszA); } if ( props ) { (*pMAPIFreeBuffer)(props); } } if ( *containerDN ) { sprintf(key,"Container.%ld.DistinguishedName",lVarSetNdx); pVarSet->put(key,containerDN); } } lVarSetNdx++; } } } sess->Logoff(0,0,0); } } if ( pRootRows ) { (*pFreeProws)(pRootRows); } if ( pRootEntry ) { pRootEntry->Release(); } if ( pRootTable ) { pRootTable->Release(); } if ( pAdrBook ) { pAdrBook->Release(); } pVarSet->put("Container.NumItems",lVarSetNdx); return hr; }