// vdir.cpp : Implementation of CsmtpadmApp and DLL registration. #include "stdafx.h" #include #include "IADM.h" #include "imd.h" #include "inetcom.h" #include "smtpadm.h" #include "vdir.h" #include "oleutil.h" #include "metafact.h" #include "metautil.h" #include "smtpcmn.h" #include "smtpprop.h" // Must define THIS_FILE_* macros to use SmtpCreateException() #define THIS_FILE_HELP_CONTEXT 0 #define THIS_FILE_PROG_ID _T("Smtpadm.VirtualDirectory.1") #define THIS_FILE_IID IID_ISmtpAdminVirtualDirectory typedef struct _VDIR_ENTRY { TCHAR szName[METADATA_MAX_NAME_LEN+2]; TCHAR szDirectory[MAX_PATH + UNLEN + 3]; TCHAR szUser[UNLEN+1]; TCHAR szPassword[PWLEN+1]; DWORD dwAccess; DWORD dwSslAccess; BOOL fLogAccess; LIST_ENTRY list; } VDIR_ENTRY, * PVDIR_ENTRY; ///////////////////////////////////////////////////////////////////////////// // STDMETHODIMP CSmtpAdminVirtualDirectory::InterfaceSupportsErrorInfo(REFIID riid) { static const IID* arr[] = { &IID_ISmtpAdminVirtualDirectory, }; for (int i=0;iFlink; pEntry!=pHead; ) { pTemp = pEntry; pEntry= pEntry->Flink; pCurVDir = CONTAINING_RECORD(pTemp, VDIR_ENTRY, list); RemoveEntryList( pTemp ); delete pCurVDir; } _ASSERT( IsListEmpty(&m_list) ); } ////////////////////////////////////////////////////////////////////// // Properties: ////////////////////////////////////////////////////////////////////// // Which service to configure: STDMETHODIMP CSmtpAdminVirtualDirectory::get_Server ( BSTR * pstrServer ) { return StdPropertyGet ( m_strServer, pstrServer ); } STDMETHODIMP CSmtpAdminVirtualDirectory::put_Server ( BSTR strServer ) { return StdPropertyPutServerName ( &m_strServer, strServer ); } STDMETHODIMP CSmtpAdminVirtualDirectory::get_ServiceInstance ( long * plServiceInstance ) { return StdPropertyGet ( m_dwServiceInstance, plServiceInstance ); } STDMETHODIMP CSmtpAdminVirtualDirectory::put_ServiceInstance ( long lServiceInstance ) { return StdPropertyPut ( (long *) &m_dwServiceInstance, lServiceInstance ); } // enumeration STDMETHODIMP CSmtpAdminVirtualDirectory::get_Count ( long * plCount ) { return StdPropertyGet ( m_lCount, plCount ); } // VirtualDirectory property STDMETHODIMP CSmtpAdminVirtualDirectory::get_VirtualName ( BSTR * pstrName ) { return StdPropertyGet ( m_strName, pstrName ); } STDMETHODIMP CSmtpAdminVirtualDirectory::put_VirtualName ( BSTR strName ) { return StdPropertyPut ( &m_strName, strName ); } STDMETHODIMP CSmtpAdminVirtualDirectory::get_Directory ( BSTR * pstrPath ) { return StdPropertyGet ( m_strDirectory, pstrPath ); } STDMETHODIMP CSmtpAdminVirtualDirectory::put_Directory ( BSTR strPath ) { return StdPropertyPut ( &m_strDirectory, strPath ); } STDMETHODIMP CSmtpAdminVirtualDirectory::get_User ( BSTR * pstrUserName ) { return StdPropertyGet ( m_strUser, pstrUserName ); } STDMETHODIMP CSmtpAdminVirtualDirectory::put_User ( BSTR strUserName ) { return StdPropertyPut ( &m_strUser, strUserName ); } STDMETHODIMP CSmtpAdminVirtualDirectory::get_Password ( BSTR * pstrPassword ) { return StdPropertyGet ( m_strPassword, pstrPassword ); } STDMETHODIMP CSmtpAdminVirtualDirectory::put_Password ( BSTR strPassword ) { return StdPropertyPut ( &m_strPassword, strPassword ); } STDMETHODIMP CSmtpAdminVirtualDirectory::get_LogAccess( BOOL* pfLogAccess ) { return StdPropertyGet ( m_fLogAccess, pfLogAccess ); } STDMETHODIMP CSmtpAdminVirtualDirectory::put_LogAccess( BOOL fLogAccess ) { return StdPropertyPut ( &m_fLogAccess, fLogAccess ); } STDMETHODIMP CSmtpAdminVirtualDirectory::get_AccessPermission( long* plAccessPermission ) { return StdPropertyGet ( m_dwAccess, plAccessPermission ); } STDMETHODIMP CSmtpAdminVirtualDirectory::put_AccessPermission( long lAccessPermission ) { return StdPropertyPut ( &m_dwAccess, lAccessPermission ); } STDMETHODIMP CSmtpAdminVirtualDirectory::get_SslAccessPermission( long* plSslAccessPermission ) { return StdPropertyGet ( m_dwSslAccess, plSslAccessPermission ); } STDMETHODIMP CSmtpAdminVirtualDirectory::put_SslAccessPermission( long lSslAccessPermission ) { return StdPropertyPut ( &m_dwSslAccess, lSslAccessPermission ); } ////////////////////////////////////////////////////////////////////// // Methods: ////////////////////////////////////////////////////////////////////// // get /set property for current vdir STDMETHODIMP CSmtpAdminVirtualDirectory::GetHomeDirectory( ) { TraceFunctEnter ( "CSmtpAdminVirtualDirectory::GetHomeDirectory" ); m_strName.Empty(); m_strName = _T(""); return Get(); } STDMETHODIMP CSmtpAdminVirtualDirectory::SetHomeDirectory( ) { TraceFunctEnter ( "CSmtpAdminVirtualDirectory::SetHomeDirectory" ); m_strName.Empty(); m_strName = _T(""); return Set(); } STDMETHODIMP CSmtpAdminVirtualDirectory::Create ( ) { TraceFunctEnter ( "CSmtpAdminVirtualDirectory::Create" ); HRESULT hr = NOERROR; CComPtr pmetabase; TCHAR szPath[METADATA_MAX_NAME_LEN+2] = {0}; if( !m_strName || !m_strDirectory ) { FatalTrace ( (LPARAM) this, "No virtual directory to create!" ); hr = E_POINTER; return hr; } hr = m_mbFactory.GetMetabaseObject ( m_strServer, &pmetabase ); if ( FAILED(hr) ) { return SmtpCreateExceptionFromHresult(hr); } CMetabaseKey hMB( pmetabase ); GetMDRootPath( szPath, m_dwServiceInstance ); hr = hMB.Open( szPath, METADATA_PERMISSION_WRITE ); BAIL_ON_FAILURE(hr); hr = hMB.CreateChild(m_strName); BAIL_ON_FAILURE(hr); if( !SetVRootPropertyToMetabase( &hMB, m_strName, m_strDirectory, m_strUser, m_strPassword, m_dwAccess, m_dwSslAccess, m_fLogAccess) ) { hr = SmtpCreateExceptionFromWin32Error( GetLastError() ); goto Exit; } hr = hMB.Save(); BAIL_ON_FAILURE(hr); Exit: if( FAILED(hr) ) { hr = SmtpCreateExceptionFromHresult(hr); } TraceFunctLeave (); return hr; } STDMETHODIMP CSmtpAdminVirtualDirectory::Delete ( ) { TraceFunctEnter ( "CSmtpAdminVirtualDirectory::Delete" ); HRESULT hr = NOERROR; CComPtr pmetabase; TCHAR szPath[METADATA_MAX_NAME_LEN+2] = {0}; if ( !m_strName ) { FatalTrace ( (LPARAM) this, "Bad dir name to delete" ); return E_POINTER; } hr = m_mbFactory.GetMetabaseObject ( m_strServer, &pmetabase ); if ( FAILED(hr) ) { return hr; } GetMDRootPath( szPath, m_dwServiceInstance ); CMetabaseKey hMB( pmetabase ); hr = hMB.Open( szPath, METADATA_PERMISSION_WRITE); BAIL_ON_FAILURE(hr); hr = hMB.DestroyChild(m_strName); BAIL_ON_FAILURE(hr); hr = hMB.Save(); BAIL_ON_FAILURE(hr); Exit: if( FAILED(hr) ) { hr = SmtpCreateExceptionFromHresult(hr); } TraceFunctLeave (); return hr; } // get /set property for current vdir STDMETHODIMP CSmtpAdminVirtualDirectory::Get( ) { TraceFunctEnter ( "CSmtpAdminVirtualDirectory::Get" ); HRESULT hr = NOERROR; CComPtr pmetabase; TCHAR szPath[METADATA_MAX_NAME_LEN+2] = {0}; TCHAR szDirectory[MAX_PATH + UNLEN + 3] = {0}; TCHAR szUser[UNLEN+1] = {0}; TCHAR szPassword[PWLEN+1] = {0}; // zero out m_strDirectory = (BSTR)NULL; m_strUser = (BSTR)NULL; m_strPassword = (BSTR)NULL; if( !m_strName ) { FatalTrace ( (LPARAM) this, "No virtual directory to create!" ); hr = E_POINTER; return hr; } hr = m_mbFactory.GetMetabaseObject ( m_strServer, &pmetabase ); if ( FAILED(hr) ) { return hr; } CMetabaseKey hMB( pmetabase ); GetMDVDirPath( szPath, m_dwServiceInstance, m_strName ); hr = hMB.Open( szPath ); if( FAILED(hr) ) { hr = SmtpCreateExceptionFromWin32Error( GetLastError() ); goto Exit; } if( !GetVRootPropertyFromMetabase( &hMB, _T(""), szDirectory, szUser, szPassword, &m_dwAccess, &m_dwSslAccess, &m_fLogAccess) ) { hr = SmtpCreateExceptionFromWin32Error( GetLastError() ); goto Exit; } m_strDirectory = szDirectory; m_strUser = szUser; m_strPassword = szPassword; Exit: TraceFunctLeave (); return hr; } STDMETHODIMP CSmtpAdminVirtualDirectory::Set( ) { TraceFunctEnter ( "CSmtpAdminVirtualDirectory::Set" ); HRESULT hr = NOERROR; CComPtr pmetabase; TCHAR szPath[METADATA_MAX_NAME_LEN+2] = {0}; if( !m_strName || !m_strDirectory ) { ErrorTrace ( (LPARAM) this, "No virtual directory to create!" ); hr = E_POINTER; return hr; } hr = m_mbFactory.GetMetabaseObject ( m_strServer, &pmetabase ); if ( FAILED(hr) ) { return hr; } CMetabaseKey hMB( pmetabase ); GetMDVDirPath( szPath, m_dwServiceInstance, m_strName ); hr = hMB.Open( szPath,METADATA_PERMISSION_WRITE ); BAIL_ON_FAILURE(hr); if( !SetVRootPropertyToMetabase( &hMB, _T(""), m_strDirectory, m_strUser, m_strPassword, m_dwAccess, m_dwSslAccess, m_fLogAccess) ) { hr = SmtpCreateExceptionFromWin32Error( GetLastError() ); return hr; } hr = hMB.Save(); Exit: if( FAILED(hr) ) { hr = SmtpCreateExceptionFromHresult(hr); } TraceFunctLeave (); return hr; } STDMETHODIMP CSmtpAdminVirtualDirectory::Enumerate( ) { TraceFunctEnter ( "CSmtpAdminVirtualDirectory::Enumerate" ); HRESULT hr = NOERROR; CComPtr pmetabase; TCHAR szPath[METADATA_MAX_NAME_LEN+2] = {0}; DWORD dwAccess; DWORD dwSslAccess; BOOL fLogAccess; TCHAR szName[METADATA_MAX_NAME_LEN+2]; TCHAR szDirectory[MAX_PATH + UNLEN + 3]; TCHAR szUser[UNLEN+1]; TCHAR szPassword[PWLEN+1]; INT i; PVDIR_ENTRY pCurVDir=NULL; hr = m_mbFactory.GetMetabaseObject ( m_strServer, &pmetabase ); if ( FAILED(hr) ) { return hr;; } GetMDRootPath( szPath, m_dwServiceInstance ); CMetabaseKey hMB( pmetabase ); hr = hMB.Open( szPath ); if( FAILED(hr) ) { hr = SmtpCreateExceptionFromHresult( hr ); goto Exit; } Clear(); // reset state, m_lCount = 0 i = 0; while( SUCCEEDED( hMB.EnumObjects(_T(""), szName, i ++) ) ) { if ( !GetVRootPropertyFromMetabase( &hMB, szName, szDirectory, szUser, szPassword, &dwAccess, &dwSslAccess, &fLogAccess) ) { continue; } pCurVDir = new VDIR_ENTRY; if( !pCurVDir ) { hr = E_OUTOFMEMORY; goto Exit; } lstrcpy( pCurVDir->szName, szName); lstrcpy( pCurVDir->szDirectory, szDirectory); lstrcpy( pCurVDir->szUser, szUser); lstrcpy( pCurVDir->szPassword, szPassword); pCurVDir-> dwAccess = dwAccess; pCurVDir-> dwSslAccess = dwSslAccess; pCurVDir-> fLogAccess = fLogAccess; InsertHeadList( &m_list, &(pCurVDir->list) ); m_lCount ++; } // _ASSERT( GetLastError() == ERROR_NO_MORE_ITEMS ); m_fEnumerateCalled = TRUE; Exit: TraceFunctLeave (); return hr; } STDMETHODIMP CSmtpAdminVirtualDirectory::GetNth ( long lIndex ) { TraceFunctEnter ( "CSmtpAdminVirtualDirectory::GetNth" ); if( lIndex < 0 || lIndex >= m_lCount ) { TraceFunctLeave (); return SmtpCreateException ( IDS_SMTPEXCEPTION_INVALID_INDEX ); } PLIST_ENTRY pEntry; PVDIR_ENTRY pVdir; INT i; if( !m_fEnumerateCalled ) { TraceFunctLeave (); return SmtpCreateException ( IDS_SMTPEXCEPTION_INVALID_INDEX ); } // zero out m_strName = (BSTR)NULL; m_strDirectory = (BSTR)NULL; m_strUser = (BSTR)NULL; m_strPassword = (BSTR)NULL; pEntry = &m_list; for( i=0; i<=lIndex; i++ ) { pEntry=pEntry->Flink; _ASSERT( pEntry != & m_list); if( pEntry == & m_list ) { TraceFunctLeave (); return SmtpCreateException ( IDS_SMTPEXCEPTION_INVALID_INDEX ); } } pVdir = CONTAINING_RECORD(pEntry, VDIR_ENTRY, list); // automatically changed to UNICODE m_strName = pVdir->szName; m_strDirectory = pVdir->szDirectory; m_strUser = pVdir->szUser; m_strPassword = pVdir->szPassword; TraceFunctLeave (); return NOERROR; } BOOL CSmtpAdminVirtualDirectory::GetVRootPropertyFromMetabase( CMetabaseKey* hMB, const TCHAR* szName, TCHAR* szDirectory, TCHAR* szUser, TCHAR* szPassword, DWORD* pdwAccess, DWORD* pdwSslAccess, BOOL* pfLogAccess ) { DWORD cb; DWORD dwDontLog = DEFAULT_LOG_TYPE; HRESULT hr = NOERROR; TraceFunctEnter ( "CSmtpAdminVirtualDirectory::GetVRootPropertyFromMetabase" ); cb = (MAX_PATH + UNLEN + 3) * sizeof(TCHAR); hr = hMB->GetString( szName, MD_VR_PATH, szDirectory,cb,0 ); if( FAILED(hr) ) { szDirectory[0] = _T('\0'); } StdGetMetabaseProp( hMB, MD_ACCESS_PERM, MD_ACCESS_READ | MD_ACCESS_WRITE, pdwAccess, szName ); StdGetMetabaseProp( hMB, MD_SSL_ACCESS_PERM, 0, pdwSslAccess, szName ); StdGetMetabaseProp( hMB, MD_DONT_LOG, DEFAULT_LOG_TYPE, &dwDontLog, szName ); *pfLogAccess = !dwDontLog; cb = sizeof(TCHAR) * (UNLEN+1); hr = hMB->GetString(szName,MD_VR_USERNAME,szUser,cb); if( FAILED(hr) ) { szUser[0] = _T('\0'); } cb = sizeof(TCHAR) * (PWLEN+1); if ( (szUser[0] != _T('\0')) && (szDirectory[0] == _T('\\')) && (szDirectory[1] == _T('\\')) ) { hr = hMB->GetString(szName,MD_VR_PASSWORD,szPassword,cb,METADATA_NO_ATTRIBUTES); if( FAILED(hr) ) { DebugTrace( (LPARAM)this, "Error %d reading path from %s\n", GetLastError(), szName); szPassword[0] = _T('\0'); } } return TRUE; } BOOL CSmtpAdminVirtualDirectory::SetVRootPropertyToMetabase( CMetabaseKey* hMB, const TCHAR* szName, const TCHAR* szDirectory, const TCHAR* szUser, const TCHAR* szPassword, DWORD dwAccess, DWORD dwSslAccess, BOOL fLogAccess ) { DWORD dwDontLog = fLogAccess ? 0 : 1; HRESULT hr = NOERROR; hr = hMB->SetString( szName,MD_VR_PATH, szDirectory ); BAIL_ON_FAILURE(hr); hr = hMB->SetDword( szName, MD_DONT_LOG, dwDontLog); BAIL_ON_FAILURE(hr); hr = hMB->SetDword( szName, MD_ACCESS_PERM, dwAccess ); BAIL_ON_FAILURE(hr); hr = hMB->SetDword( szName, MD_SSL_ACCESS_PERM, dwSslAccess); BAIL_ON_FAILURE(hr); if( szUser[0] ) { hr = hMB->SetString( szName, MD_VR_USERNAME, szUser); } if( szPassword[0] ) { hr = hMB->SetString( szName, MD_VR_PASSWORD, szPassword, METADATA_INHERIT | METADATA_SECURE ); } Exit: if( FAILED(hr) ) { SetLastError(hr); return FALSE; } return TRUE; }